I have a filter object that comes from an OpenAPI spec; something like:
export interface Filters {
field1: string[]
field2: string[]
field3: boolean
field4: number
}
I'd like to derive a type from that filters interface by selecting the type of the properties:
Something like:
export type MultivalueFields = Select<Filters, string[]>
// type MultivalueFields = 'field1' | 'field2'
Is there a builtin for this? How can one get the desired outcome?
CodePudding user response:
You can build a utility type such as follows:
type Values<T> = T[keyof T]
type Select<T, SelectType> = Values<{
[Prop in keyof T]: T[Prop] extends SelectType ? Prop : never
}>
// typeof A = 'field1'
type A = Select<{field1: string[], field2: string}, string[]>
All credit goes to @captain-yossarian from Ukraine
CodePudding user response:
There are several version of types that do this. The most modern one is usig the as
clause in mapped types:
type Select<T, SelectType> = keyof {
[Prop in keyof T as T[Prop] extends SelectType ? Prop : never]: any
}
// typeof A = 'field1'
type A = Select<{field1: string[], field2: string}, string[]>
You can also use a similar type to pick properties of a specific type:
type PickByType<T, SelectType> = {
[Prop in keyof T as T[Prop] extends SelectType ? Prop : never]: T[Prop]
}
// typeof A = { field1: string[]; }
type A = PickByType<{field1: string[], field2: string}, string[]>