TypeScript: レコードの Optional なプロパティの型のみ(あるいはその逆)を抽出する
February 22, 2022
こんな型があるとします。
type Person = {
name: string;
age: number;
isAdult: boolean;
siblings: string[];
birthplace?: string;
height?: number;
hasPartner?: boolean;
friends?: string[];
};
こうすれば Optional なプロパティのみを抽出できます。
type OptionalPropertyKeys<T> = {
[K in keyof T]-?: undefined extends T[K] ? K : never;
}[keyof T];
type OptionalPersonPropertyKeys = OptionalPropertyKeys<Person>;
// 👉 "birthplace" | "height" | "hasPartner" | "friends"
type OptionalPersonProperty = Pick<Person, OptionalPersonPropertyKeys>;
// 👉 {
// birthplace?: string;
// height?: number;
// hasPartner?: boolean;
// friends?: string[];
// }
/**
* ということでこうして使いましょう。
*/
type OptionalProperty<T> = Pick<
T,
{
[K in keyof T]: undefined extends T[K] ? K : never;
}[keyof T]
>;
逆に、Required なプロパティのみを抽出するならばこうです。
type RequiredPropertyKeys<T> = {
[K in keyof T]-?: undefined extends T[K] ? never : K;
}[keyof T];
type RequiredPersonPropertyKeys = RequiredPropertyKeys<Person>;
// 👉 "name" | "age" | "isAdult" | "siblings"
type RequiredPersonProperty = Pick<Person, RequiredPersonPropertyKeys>;
// 👉 {
// name: string;
// age: number;
// isAdult: boolean;
// siblings: string[];
// }
/**
* ということでこうして使いましょう。
*/
type RequiredProperty<T> = Pick<
T,
{
[K in keyof T]: undefined extends T[K] ? never : K;
}[keyof T]
>;
あるいは任意の型で抽出したいならば、ジェネリックをもう1つ貰うようにすれば良いです。
type PickedTypeProperty<T, U> = Pick<
T,
{
[K in keyof T]: T[K] extends U ? K : never;
}[keyof T]
>;
type StringPersonProperty = PickedTypeProperty<Person, string>;
// 👉 { name: string; }
type StringOrNumberPersonProperty = PickedTypeProperty<Person, string | number>;
// 👉 { name: string; age: number; }