今回はこういった疑問に答えます。
少しでもTypeScriptを用いた開発をする際の参考になれば幸いです。
オブジェクト型の一部のプロパティをNonNullableにする【TypeScript】
以下のようなオブジェクト型があり、このうちプロパティaとcの型をNonNullableにしたい状況です。
type Sample = { a: string | null; b: number; c: { hoge: string; huga: number; } | null; };
この場合、以下のような型を作成することで、指定したプロパティのみNonNullableにすることができます。
type PartialNotNullable<T, K extends keyof T> = Omit<T, K> & { [P in K]: NonNullable<T[P]>; };
実装の中身を解説していきます。
<T, K extends keyof T>はジェネリクスの部分です。
これにより、TとKに任意の値を渡すことができます。
keyofは、後ろに指定したオブジェクト型のプロパティ名をユニオン型で返すキーワードです。
例えば、TにSample型を渡した場合、keyof Tは’a’ | ‘b’ | ‘c’になります。
そして、extendsは型Kを特定の型に限定するためのキーワードです。
今回の場合は、TにはSampleが入るため、Kは’a’,’b’,’c’のいずれかに限定されます。
Omitはオブジェクト型TからプロパティKを削除するユーティリティ型です。
例えばOmit<Sample, ‘a’>とした場合、Sapmle型からプロパティaを削除した新たな型が生成されます。
&は型をマージするキーワードです。
{[P in K]: NonNullable<T[P]>} はMapped Typesと呼ばれる記法です。
Mapped Typesとは、一言でいうと、プロパティ名のユニオン型Kを展開して新たなオブジェクト型を定義する手法のことです。
例えばKに’a’と’c’を指定した場合、Pにはaとcが入り、aとcのプロパティを持つオブジェクト型が新たに生成されます。
そして、NonNullable<T[P]>の部分がそれぞれのプロパティで定義される値です。
T[P]はオブジェクト型TからプロパティPの型を抜き出すキーワードです。例えば、Sample[“a”]は string | null になります。
NonNullableはユニオン型からnullとundefinedを削除するキーワードです。
例えばNonNullable<string | null>はstring型になります。
まとめると、以下の型はオブジェクト型TからプロパティKを一旦取り除いた上で、プロパティKの型からnullとundefinedを削除していると言えるでしょう。
type PartialNotNullable<T, K extends keyof T> = Omit<T, K> & { [P in K]: NonNullable<T[P]>; };
実際、以下のようにSample型をこの型に通してみます。
type UpdatedSample = PartialNonNullable<Sample, "a" | "c">;
すると、以下のようにaとcからnullが削除されます。
おわりに
今回はTypeScriptでオブジェクト型の一部のプロパティをNonNullableにする方法を解説しました。
TypeScriptを使って実装をする上でこの記事が少しでも参考になっていれば幸いです。