create stricter type

what's the right way to create a type using the actual field names of an object that is currently { [x:string]: Foo }? will keyof typeof actually do the magic?
15 Replies
Alejandro Mery
Alejandro Mery2mo ago
nope, keyof typeof table gives string | number instead of the list of keys
Reinier Kaper
Reinier Kaper2mo ago
If you have an object, you can use something like this:
export const COUNTRY_CURRENCIES = {
US: 'USD',
CA: 'CAD',
} as const
export type COUNTRY_CURRENCIES = (typeof COUNTRY_CURRENCIES)[keyof typeof COUNTRY_CURRENCIES]
export const COUNTRY_CURRENCIES = {
US: 'USD',
CA: 'CAD',
} as const
export type COUNTRY_CURRENCIES = (typeof COUNTRY_CURRENCIES)[keyof typeof COUNTRY_CURRENCIES]
keyof typeof should give you the keys though Hm, { [x:string]: Foo } looks odd though, you indeed get string/number
Alejandro Mery
Alejandro Mery2mo ago
I want to programmatically add fields to the object and then turn it into a strict type but as soon as I give a type to the target object it sticks permanently either { [x:string]: Foo } or Record<string,Foo> e.g.
export type standardDynamicSchemeFactory = (primary: HexColor | Hct | number, isDark: boolean, contrastLevel: number) => DynamicScheme;

export const standardDynamicSchemes: Record<string, standardDynamicSchemeFactory> = {
content: (primary, isDark = false, contrastLevel = 0) => new SchemeContent(hct(primary), isDark, contrastLevel),
expressive: (primary, isDark = false, contrastLevel = 0) => new SchemeExpressive(hct(primary), isDark, contrastLevel),
fidelity: (primary, isDark = false, contrastLevel = 0) => new SchemeFidelity(hct(primary), isDark, contrastLevel),
monochrome: (primary, isDark = false, contrastLevel = 0) => new SchemeMonochrome(hct(primary), isDark, contrastLevel),
neutral: (primary, isDark = false, contrastLevel = 0) => new SchemeNeutral(hct(primary), isDark, contrastLevel),
tonalSpot: (primary, isDark = false, contrastLevel = 0) => new SchemeTonalSpot(hct(primary), isDark, contrastLevel),
vibrant: (primary, isDark = false, contrastLevel = 0) => new SchemeVibrant(hct(primary), isDark, contrastLevel),
};

export type standardDynamicSchemeKey =
'content' | 'expressive' | 'fidelity' |
'monochrome' | 'neutral' | 'tonalSpot' | 'vibrant';
export type standardDynamicSchemeFactory = (primary: HexColor | Hct | number, isDark: boolean, contrastLevel: number) => DynamicScheme;

export const standardDynamicSchemes: Record<string, standardDynamicSchemeFactory> = {
content: (primary, isDark = false, contrastLevel = 0) => new SchemeContent(hct(primary), isDark, contrastLevel),
expressive: (primary, isDark = false, contrastLevel = 0) => new SchemeExpressive(hct(primary), isDark, contrastLevel),
fidelity: (primary, isDark = false, contrastLevel = 0) => new SchemeFidelity(hct(primary), isDark, contrastLevel),
monochrome: (primary, isDark = false, contrastLevel = 0) => new SchemeMonochrome(hct(primary), isDark, contrastLevel),
neutral: (primary, isDark = false, contrastLevel = 0) => new SchemeNeutral(hct(primary), isDark, contrastLevel),
tonalSpot: (primary, isDark = false, contrastLevel = 0) => new SchemeTonalSpot(hct(primary), isDark, contrastLevel),
vibrant: (primary, isDark = false, contrastLevel = 0) => new SchemeVibrant(hct(primary), isDark, contrastLevel),
};

export type standardDynamicSchemeKey =
'content' | 'expressive' | 'fidelity' |
'monochrome' | 'neutral' | 'tonalSpot' | 'vibrant';
even being pretty static I just can't make a keys type my other use-case composes keys based on the keys of one of the arguments https://github.com/poupe-ui/poupe/blob/main/packages/theme-builder/src/colors.ts#L61 and https://github.com/poupe-ui/poupe/blob/main/packages/theme-builder/src/colors-data.ts#L111 for the above paste
MEE6
MEE62mo ago
joe_black_unlucky has been warned
Reason: Posted an invite
joe_black_unlucky
I didn't really want to invite you to another discord, just suggesting that you should maybe go ask at a typescript community, this is more of a nuxt centered community And then my 2 cents: Don't get bogged down with perfectly typing everything, while you are spending hours figuring this out your productivity is zero and solving this is also zero toward completing any task, perfectly typing things does not solve anything. Unless you work for a big coporate that doesn't mind tasks taking weeks to complete
Alejandro Mery
Alejandro Mery2mo ago
any recommended discord server focused on typescript? it's quite annoying the discussion channels got closed here It's not a blocker indeed, mostly curiosity. but I am a strong-typed systems developer (C,Go) moving out of my comfort zone a bit trying to learn from vue/nuxt devs how to make front-end stuff "the right way" 🤷‍♂️
joe_black_unlucky
I got a warning from the mods sharing a link, just google for typescript discord server, there is one
Alejandro Mery
Alejandro Mery2mo ago
thank you!
manniL
manniL2mo ago
nah, that was automod maybe try https://discord.com/invite/typescript
joe_black_unlucky
That's the link I shared and got automodded 🙂
manniL
manniL2mo ago
I know 😄 - Discord invite spam is too strong nowadays
Alejandro Mery
Alejandro Mery2mo ago
thank you, I recently cancelled my discord subscription and not I'm being told I can't join more servers 😭 frustratingly it doesn't tell me how many I need to leave 😕 I may just create another account 😅
manniL
manniL2mo ago
max is 50 or so I think
Alejandro Mery
Alejandro Mery2mo ago
I never thought that as a factor to get Nitro so, the answer is declaring the object using satisfies
--- a/packages/theme-builder/src/colors-data.ts
+++ b/packages/theme-builder/src/colors-data.ts
@@ -108,7 +108,7 @@ export const contentAccentToneDelta = MaterialDynamicColors.contentAccentToneDel

// DynamicScheme
//
-export const standardDynamicSchemes: Record<string, standardDynamicSchemeFactory> = {
+export const standardDynamicSchemes = {
content: (primary, isDark = false, contrastLevel = 0) => new SchemeContent(hct(primary), isDark, contrastLevel),
expressive: (primary, isDark = false, contrastLevel = 0) => new SchemeExpressive(hct(primary), isDark, contrastLevel),
fidelity: (primary, isDark = false, contrastLevel = 0) => new SchemeFidelity(hct(primary), isDark, contrastLevel),
@@ -116,8 +116,6 @@ export const standardDynamicSchemes: Record<string, standardDynamicSchemeFactory
neutral: (primary, isDark = false, contrastLevel = 0) => new SchemeNeutral(hct(primary), isDark, contrastLevel),
tonalSpot: (primary, isDark = false, contrastLevel = 0) => new SchemeTonalSpot(hct(primary), isDark, contrastLevel),
vibrant: (primary, isDark = false, contrastLevel = 0) => new SchemeVibrant(hct(primary), isDark, contrastLevel),
-};
+} satisfies Record<string, standardDynamicSchemeFactory>;

-export type standardDynamicSchemeKey =
- 'content' | 'expressive' | 'fidelity' |
- 'monochrome' | 'neutral' | 'tonalSpot' | 'vibrant';
+export type standardDynamicSchemeKey = keyof typeof standardDynamicSchemes;
--- a/packages/theme-builder/src/colors-data.ts
+++ b/packages/theme-builder/src/colors-data.ts
@@ -108,7 +108,7 @@ export const contentAccentToneDelta = MaterialDynamicColors.contentAccentToneDel

// DynamicScheme
//
-export const standardDynamicSchemes: Record<string, standardDynamicSchemeFactory> = {
+export const standardDynamicSchemes = {
content: (primary, isDark = false, contrastLevel = 0) => new SchemeContent(hct(primary), isDark, contrastLevel),
expressive: (primary, isDark = false, contrastLevel = 0) => new SchemeExpressive(hct(primary), isDark, contrastLevel),
fidelity: (primary, isDark = false, contrastLevel = 0) => new SchemeFidelity(hct(primary), isDark, contrastLevel),
@@ -116,8 +116,6 @@ export const standardDynamicSchemes: Record<string, standardDynamicSchemeFactory
neutral: (primary, isDark = false, contrastLevel = 0) => new SchemeNeutral(hct(primary), isDark, contrastLevel),
tonalSpot: (primary, isDark = false, contrastLevel = 0) => new SchemeTonalSpot(hct(primary), isDark, contrastLevel),
vibrant: (primary, isDark = false, contrastLevel = 0) => new SchemeVibrant(hct(primary), isDark, contrastLevel),
-};
+} satisfies Record<string, standardDynamicSchemeFactory>;

-export type standardDynamicSchemeKey =
- 'content' | 'expressive' | 'fidelity' |
- 'monochrome' | 'neutral' | 'tonalSpot' | 'vibrant';
+export type standardDynamicSchemeKey = keyof typeof standardDynamicSchemes;
Reinier Kaper
Reinier Kaper2mo ago
Interesting, I should look into that