Typescript Generate Full Path Type And Get Value Type Of Nested Union Object With Numeric Key
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:
- nested
- numeric keys
- unions
There is one serious flaw with this approach, do you know what it is and how to fix it? (hint: collapsing path)