オブジェクトのプロパティを連結してUnion型をつくる
オブジェクトのプロパティを連結してFoo | Foo.Bar | Foo.Bar.Baz
のようなUnion Typeがほしいときがある。
type Primitive =
| null
| undefined
| string
| number
| boolean
| symbol
| bigint
type PathImpl<K extends string | number, V> =
V extends Primitive
? `${K}`
:`${K}` | `${K}.${Path<V>}`
type Path<T> =
T extends ReadonlyArray<infer V>
? PathImpl<number, V>
: {
[K in keyof T]-?: PathImpl<K & string, T[K]>
}[keyof T]
これをこうすると…
type Item = {
Foo: {
Bar: {
Baz: string
}
}
Hoge: {
Fuga: string
}
}
type test = Path<Item>
// ^? 'Foo' | 'Foo.Bar' | 'Foo.Bar.Baz' | 'Hoge' | 'Hoge.Fuga'