Typescript Generate Full Path Type And Get Value Type Of Nested Union Object With Numeric Key
Acid Coder

Acid Coder @tylim88

About: Who needs meth when you have Typescript?

Joined:
Oct 31, 2021

Typescript Generate Full Path Type And Get Value Type Of Nested Union Object With Numeric Key

Publish Date: Dec 14 '22
9 4

Before TS 4.8, obtaining value type for path A/${number} of { A: Record<number, boolean> } is possible, that is type B = DeepValue<A/${number}> // boolean

however it is impossible to get the value type for path A/${123} of { A: { 123: boolean } }, type B = DeepValue<A/${123}> // never

With TS 4.8, Improved Inference for infer Types in Template String Types made numeric literal path type possible

type DeepKey<
    T,
    K extends keyof T = keyof T
> = K extends string | number
    ? T[K] extends infer R 
        ? `${K}`| (R extends Record<string, unknown> ? `${K}/${DeepKey<R>}` : never) 
        : never // impossible route
    : never // impossible route

type DeepValue<
    T,
    P extends DeepKey<T>,
> = P extends `${infer K}/${infer Rest}`
    ? T[(K extends `${infer R extends number}` ? R : K) & keyof T] extends infer S
        ? S extends never // make S distributive to work with union object
            ? never
            : Rest extends DeepKey<S>
                ? DeepValue<S, Rest>
                : never // impossible route
            : never // impossible route
    : T[(P extends `${infer R extends number}` ? R : P) & keyof T]
Enter fullscreen mode Exit fullscreen mode

Image description

support:

  1. nested
  2. numeric keys
  3. unions

playground

There is one serious flaw, do you know what it is and how to fix it? (hint: collapsing path)

Comments 4 total

  • Martin Ragan
    Martin RaganSep 25, 2023

    type XD = {x: string} | {b: number}; is giving incorrect output by your type in my opinion

    • Acid Coder
      Acid CoderSep 26, 2023

      ya, it does not work with top level unions because

      type I = keyof ({x: string} | {b: number})
      //   ^? never
      
      Enter fullscreen mode Exit fullscreen mode
      • Martin Ragan
        Martin RaganSep 28, 2023

        This can be solvable easily. But recursive types are cryptonit for this.

        • Acid Coder
          Acid CoderSep 28, 2023

          It is, but this is not the flaw that in my mind. The flaw is more specific to this case, not to recursive type in overall

Add comment