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

Acid Coder
2 min readDec 14, 2022

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]

support:

  1. nested
  2. numeric keys
  3. unions

playground

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

--

--

Acid Coder

Typescript Zombie. Youtube Pikachu On Acid. (Unrelated to programming but by watching it you become a good developer overnight)