⚙️

TypeScriptのPickをTypeで指定できるやつ。

2021/09/03に公開

やりたいこと

こういうことをしたい。

type T1 = {
    a: number,
    b: string,
};

type T2 = PickUpByType<T1, number>;

const t2: T2 = {
    a: 1,
};

解決

実装はこう

type KeysByType<T, Type> = {
  [key in keyof T]: T[key] extends Type ? key : never;
}[keyof T];

type PickUpByType<T, Type> = Pick<T, KeysByType<T, Type>>;

参考文献
https://github.com/microsoft/TypeScript/issues/16350#issuecomment-397374468

解説

{
  [key in keyof T]: T[key] extends Type ? key : never;
}

この部分ではタイプでフィルターしながら {[key]: key} というタイプを作っている。

つまり

type A = {
    a: number;
    b: string;
}

↑が↓になる。

type A = {
    a: 'a';
    b: never;
}

で最後の↓の部分でstringのunionに変換する, このタイミングで never なキーが除外される。

}[keyof T]

つまり

type A = {
    a: 'a',
    b: never
}

↑が↓になる。

type A = 'a';

あとは Exclude でなんやかんやすればいい。

Discussion