≪ Today I learned.
RSS購読
    公開日
    タグ
    TypeScript
    著者
    ダーシノ

    オブジェクトのプロパティを連結して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'