Closed4
TypeScript の Optional Property を型で判定する
やりたいこと
以下のような Optional Property を持つ型があるとします👇
type Hoge = {
foo: string
bar: number | undefined
hoge?: string
}
上記の型から Optional Property である hoge
のみを取り出す型関数を作りたいです 👇
type Hoge = {
foo: string
bar: number | undefined
hoge?: string
}
type OnlyOptionalProperties = PickOptionalProperties<Hoge>;
// 結果は `{ hoge?: string }` としたい
実現方法
以下のような型を作成することで実現できます👇
type PickOptionalProperties<T extends object> = Pick<T, {
[K in keyof T]: T[K] extends Required<T>[K] ? never : K
}[keyof T]>
解説
この場合の肝となるのは Union 型をどうやって排除するかというところですが、組み込み型である Required を使うことで、 Optional Property のみに型の差分を作り出すことできます 👇
type A = Required<Hoge>;
/*
{
foo: string
bar: number | undefined
hoge: string // 👈 Optional Property だけ型が変わってる
}
*/
これを利用することで、Optional Property か判定することができます。
具体的には以下の部分ですね👇
// この条件式の場合 Optional Property だけが `K` を返す
[K in keyof T]: T[K] extends Required<T>[K] ? never : K
あとはプロパティ名を値に持つオブジェクト型を作って、そこからプロパティ名のUnion型に変換して、Pick を使って Optional Property のみを抜き出すという感じです 👇
type PickOptionalProperties<T extends object> = Pick<
T,
// プロパティ名を値に持つオブジェクト型を作って、そこからプロパティ名のUnion型に変換
{
[K in keyof T]: T[K] extends Required<T>[K] ? never : K
}[keyof T]
>
Ref
このスクラップは2023/01/09にクローズされました