0

Does exist, or is there a way, to be able to use something like this:

type X<Obj, FieldType> = ???;

interface A {
  a: number;
  b: number;
  c: string;
  d: Date;
}

type Nums = X<A, number>;    // == 'a' | 'b'
type Strings = X<A, string>; // == 'c'
type Dates = X<A, Date>;     // == 'd'

where X is the generic type I am looking for (subset of keyof Obj, in this case keyof A).

menfon
  • 1,587
  • 1
  • 11
  • 28

1 Answers1

1

You can use a conditional type to filter properties of the desired type:

type X<Obj, FieldType> = {
    [P in keyof Obj]-?: Obj[P] extends FieldType ? P : never
}[keyof Obj];

interface A {
    a: number;
    b: number;
    c: string;
    d: Date;
}

type Nums = X<A, number>;    // == 'a' | 'b'
type Strings = X<A, string>; // == 'c'
type Dates = X<A, Date>;     // == 'd'

You can checkout my explanation of this here

Titian Cernicova-Dragomir
  • 230,986
  • 31
  • 415
  • 357
  • While my question is a duplicate (I failed to find the other question), the answer seems to be different. Namely the `-?`. Thank you for responding, I'll have to try it on monday. I remember I saw similar solution and tried it, but types produced by it were somehow broken. Oh, I might be confusing it with filtering fields by type where result type with strict TS settings wouldn't be constructible (or at least it seemed that way - compiler complaining there were missing fields of type `never`). – menfon Apr 05 '19 at 18:43