To ensure correct inference of string literals, you can use generics to define Child
and Parent
, with a generic constraint K extends string
:
type Parent<K extends string> = {
children: Child<K>[]
}
type Child<K extends string> = {
label: K
}
type Labels<P extends Parent<any>> = P extends Parent<infer K>
? { [Key in K]: string } : never;
An efficient way to automatically infer label keys from string literals is by using a helper function to assist when defining the parent
value:
function Parent<K extends string>(parent: Parent<K>) {
return parent;
}
const p1 = Parent({
children: [
{ label: 'label1' },
{ label: 'label2' }
]
})
Create a helper type that leverages inference and object mapping to transform the keys into the Labels
type:
type Labels<P extends Parent<any>> = P extends Parent<infer K>
? { [Key in K]: string } : never;
type Labels1 = Labels<typeof p1>;
// Labels1 now represents `{ label1: string; label2: string }`
Experience this functionality firsthand on the TypeScript Playground here