I'm trying to write a TypeScript type that turns a tuple of the keys of an type into a type with only those properties. The following code is the closest I have gotten:
type Primitive = string | number | boolean;
type ExtractProps<TObject, TKeys extends (keyof TObject)[], TExtends = any> = {
[Index in keyof TKeys as TKeys[Index] extends keyof TObject ? (TObject[TKeys[Index]] extends TExtends ? TKeys[Index] : never) : never ]:
TKeys[Index] extends keyof TObject ? TObject[TKeys[Index]] : never
};
type Type = {
'string': string;
'number': number;
'boolean': boolean;
'array': Array<any>
}
type Test1 = ExtractProps<Type, ['string', 'number', 'array']>;
// Output:
// type Test1 = {
// string: string | number | any[];
// number: string | number | any[];
// array: string | number | any[];
// }
// Desired Output:
// type Test1 = {
// string: string;
// number: number;
// array: any[];
// }
type Test2 = ExtractProps<Type, ['string', 'number', 'array'], Primitive>;
// Output:
// type Test2 = {
// string: string;
// number: number;
// }
// Desired Output:
// type Test2 = {
// string: string;
// number: number;
// }
type Test3 = ExtractProps<Type, ['string', 'number'], Primitive>;
// Output:
// type Test3 = {
// string: string | number;
// number: string | number;
// }
// Desired Output:
// type Test3 = {
// string: string;
// number: number;
// }
I can only get the type to work properly when the re-mapping expression evaluates to never
for one of the keys (like array
in Type2 as the property type does not extend Primitive
). Is there a way of writing ExtractProps
so that Type1 and Type3 have the correct property types?