🧩
【TypeScript】Object型から任意の型のフィールドのみを抽出する
開発中になるほどなと思ったので備忘録として&Zennデビューしたかったので投稿します.
やりたいこと
例えば,以下の Person
型から, number
型のフィールドのみを取り出したい.
type Person = {
name : string;
kanaName: string;
age: number;
height: number;
}
PickByType
任意の型のフィールドのみを抽出する 以下の PickByType
を使うことで任意の型のフィールドのみを抽出することができる.
type PickByType<T extends Record<string, unknown>, PickedType = unknown> = Pick<
T,
{
[K in keyof T]: T[K] extends PickedType ? K : never;
}[keyof T]
>;
type NumericPersonFields = PickByType<Person, number>;
/*
type NumericPersonFields = {
age: number;
height: number;
}
*/
仕組み
Pick<Type, Keys>
は Type
から Keys
で指定したフィールドを抽出する組み込み型である.
PickByType
中の Pick
の [K in keyof T]: T[K] extends PickedType ? K : never;
は 各 フィールドが PickedType
を満たしていればそのフィールドの key (K
) を返し,満たしていなければ never
を返す.
したがって, type NumericPersonFields = PickByType<Person, number>;
のときは以下のような値をとる.
// `type NumericPersonFields = PickByType<Person, number>;` のときの
// { [K in keyof T]: T[K] extends PickedType ? K : never; } の結果
{
name : never;
kanaName: never;
age: "age";
height: "height";
}
上記の結果にさらに [keyof T]
を加えることで, "age" | "height"
という Union型になる.
[keyof T]
を取ることで, never
型 の key が排除されるところがポイントである.
このような仕組みで, type NumericPersonFields = PickByType<Person, number>;
は
type NumericPersonFields = Pick<Person, "age" | "height">;
と処理されて, 指定した型のみのフィールドを抽出できる.
Discussion