Typescript: Suggestion: Pick by type

Created on 8 Jun 2017  ·  4Comments  ·  Source: microsoft/TypeScript

TypeScript Version: 2.2.1 / nightly (2.2.0-dev.201xxxxx)

Code

// A *self-contained* demonstration of the problem follows...
interface AnInterface {
  stringProperty: string;
  numberProperty: number;
  objectProperty: object;
  functionProperty1: () => number;
  functionProperty2: Function;
  functionProperty3(): number;
}
type PickByType<O extends object, T extends any> = {
  // suggestion here: we should be able to filter object property somehow.
  [K in keyof O && typeof O[K] is T]: O[K];
};
type StringOnly = PickByType<AnInterface, string>; // { stringProperty: string; }
type NumberOnly = PickByType<AnInterface, number>; // { numberProperty: number; }
type ObjectOnly = PickByType<AnInterface, object>; // { objectProperty: object; }
type WithoutFunction = StringOnly & NumberOnly & ObjectOnly; // { stringProperty: string; numberProperty: number; objectProperty: object; }  


Expected behavior:
In this scenario, we can pick object's properties by their type.
It will be useful when extracting properties from class type.

Actual behavior:
I couldn't find the way to achieve this scenario.
And also, complex index signature like K in keyof O && typeof O[K] is T is not supported yet.

Duplicate

Most helpful comment

You want to filter the keys:

type NoneStringKeys<T> = {
    [P in keyof T]: T[P] extends string ? never :P;
}[keyof T];
type OmitString<T> = Pick<T, Exclude<keyof T, NoneStringKeys<T>>>;

All 4 comments

@mhegazy Sorry for bothering you, I didn't find out a meet solution from #12424

I tried this:

type OmitString<T> = {
    [P in keyof T]: T[P] extends string ? never : T[P];
};
type T = OmitString<{ foo: string, bar: number }>;

// T is expanded as:
type T = { foo: never; bar: number; }

We lost the 'in' operator type guard in this way. I expected T is:

type T = { bar: number; }

You want to filter the keys:

type NoneStringKeys<T> = {
    [P in keyof T]: T[P] extends string ? never :P;
}[keyof T];
type OmitString<T> = Pick<T, Exclude<keyof T, NoneStringKeys<T>>>;

@mhegazy Thx very much! I learned from you.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

CyrusNajmabadi picture CyrusNajmabadi  ·  3Comments

uber5001 picture uber5001  ·  3Comments

fwanicka picture fwanicka  ·  3Comments

wmaurer picture wmaurer  ·  3Comments

siddjain picture siddjain  ·  3Comments