crazyones110
crazyones110

Reputation: 397

filter an interface or type by property types

I have this type

type Obj = {
  name: string;
  age: number;
  birth: Date;
  weight: number;
  height: number;
}

I want to filter Obj whose properties extend number | string, namely I want to get

type Filtered = {
  name: string;
  age: number;
  weight: number;
  height: number;
}

I looked up Typescript utility types, but none satisfied my needs. How can I achieve this?

Upvotes: 0

Views: 148

Answers (1)

Karol Majewski
Karol Majewski

Reputation: 25790

Use a helper that finds properties based on their values:

type PropertyOfValue<T, V> = {
  [K in keyof T]-?: T[K] extends V
    ? K
    : never
}[keyof T];

Now we can find the properties we're looking for by doing and pick them from the source object:

type Filtered = Pick<Obj, PropertyOfValue<Obj, string | number>>

Bonus

If you like, you can abstract the pattern of picking by value and put it in the global namespace.

declare global {
  namespace Pick {
    type ByValue<T, U> = Pick<T, PropertyOfValue<T, U>>
  }
}

Usage:

type Filtered = Pick.ByValue<Obj, string | number>

Upvotes: 2

Related Questions