partial<T>
TSのmapped typesを利用して提供されている便利な型partial<T>
がある
type Partial<T> = { [P in keyof T]?: T[P]; };
これが提供されているので
例えば以下のようなfoo
型のプロパティをすべてオプショナル(?:
の形式)にしたかったらこうすればよい。
interface foo { foo: string bar: string baz: number } type optionalFoo = partial<foo>
とすると
interface optionalFoo { foo?: string | undefined bar?: string | undefined baz?: number | undefined }
と同じことをしていることになる。
便利。
ネストがある場合問題あり
partial<T>
便利なのだけど、ネストした型がある場合、ネストされたやつまではoptionalな形式に変換してくれない。ネストされたものもすべてオプショナルに変換したいときこれでは困る。
interface foo { foo: string bar: string baz: { hoge: string piyo: string fuga: number } }
こういう状態のやつ
これをpartial<T>
すると
interface optionalFoo { foo?: string | undefined bar?: string | undefined baz?: { hoge: string piyo: string fuga: number } }
となってしまう。
解決方法
俺はネストされた型もすべてオプショナルにしたいんだよねという場合はpartial<T>
がrecursiveな挙動をするようなmapped types型を自分で書いてやればOKらしい
type NestedPartial<T> = { [K in keyof T]?: T[K] extends Array<infer R> ? Array<NestedPartial<R>> : NestedPartial<T[K]> }
TS2.8以降はこうすればArrayがあっても大丈夫とのことらしい。
というわけで
type NestedPartial<T> = { [K in keyof T]?: T[K] extends Array<infer R> ? Array<NestedPartial<R>> : NestedPartial<T[K]> }; interface foo { foo: string bar: string baz: { hoge: string piyo: string fuga: number } } type optionalFoo = NestedPartial<foo>
こうすればネストされた型も全部オプショナルに変換された。
ありがとうstackoverflow 🙏🙏🙏