Currently, I am developing a function that takes in a configuration parameter, which is essentially an object with a highly variable structure. Depending on the type of configuration provided, the function should output something of equally diverse structure. My aim is to maximize TypeScript inferrence for detecting the config type while also allowing users to hint at certain parts of it.
The following snippet accomplishes my objective:
type Type<T> = (_: T) => T;
const type =<T>(): Type<T> => T => T;
type ListConfig<T> = {
itemType: Type<T>;
}
type Config = {
[name: string]: ListConfig<any>;
}
type ItemType<L> = L extends ListConfig<infer T> ? T : never;
const createLists = <C extends Config>(
cfg: C
): { [K in keyof C]: Array<ItemType<C[K]>> } => {
return {} as any;
}
const config = {
numbers: {
itemType: type<number>(),
},
strings: {
itemType: type<string>(),
}
};
// The result correctly inferred as { numbers: number[], strings: string[] }
const lists = createLists(config);