After discovering this revolutionary piece of code in the
Typescript: deep keyof of a nested object link,
type Cons<H, T> = T extends readonly any[] ?
((h: H, ...t: T) => void) extends ((...r: infer R) => void) ? R : never
: never;
type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...0[]]
type Paths<T, D extends number = 10> = [D] extends [never] ? never : T extends object ?
{ [K in keyof T]-?: [K] | (Paths<T[K], Prev[D]> extends infer P ?
P extends [] ? never : Cons<K, P> : never
) }[keyof T]
: [];
This incredible code snippet helps us extract the nested paths of an object as union tuples, like so:
type Obj = {
A: { a1: string }
B: { b1: string, b2: { b2a: string } }
}
type ObjPaths = Paths<Obj> // ['A'] | ['A', 'a1'] | ['B'] | ['B', 'b1'] | ['B', 'b2'] | ['B', 'b2', 'b2a']
I am on a quest to find a way to retrieve a type from a nested property using a path tuple, structured as follows:
type TypeAtPath<T extends object, U extends Paths<T>> = ...
The issue I am facing is that the compiler shows me the error message:
Type instantiation is excessively deep and possibly infinite
.
Fortunately, I stumbled upon a solution to eliminate this error by specifying T
more precisely:
type TypeAtPath<T extends {[key: string]: any}, U extends Paths<T>> = T[U[0]]
However, this method only functions for top-level paths, and I fear my TypeScript skills may not be sufficient for this challenge.