Context: I'm making function that accepting const asserted argument:
function langs<T extends Partial<Record<Lang, LangDict>>>(dict: T & Record<keyof T, UnionToIntersection<UnConst<T[keyof T]>>>) {
return () => dict[lang() as keyof T];
}
So I will able to see missing properties in my i18n dictionary:
const t = langs({
ru: {
title: (name) => `Привет ${name}`,
placeholder: 'Введите текст',
},
en: {
title: (name) => `Hello, ${name}`,
placeholder: 'Write text',
},
} as const);
I need to create union of all types that are properties of parent type:
type Lang = 'en' | 'ru' | 'de' | 'zh' | ...etc
type Dict = Partial<Record<Lang, LangDict>>;
type UnConst<T> = { [P in keyof T]:
T[P] extends string ? string : T[P] extends ((...args: string[]) => string) ? ((...args: string[]) => string) : UnConst<T[P]>
};
type Intersection = UnConst<Dict['ru']> & UnConst<Dict['en']> & UnConst<Dict['zh']> // ...a lot of types here
But I don't want to handle in manually. As I see, UnConst<Dict[Lang]> is not the same as UnConst<Dict['ru']> & UnConst<Dict['en']> & UnConst<Dict['zh']> & ...
Is there shorthand to get same type as: Intersection without manual intersecting all keys?
Full example: https://tsplay.dev/w65jEW
