ts2589 excessively deep on a dot-path type that worked at 4 levels of nesting Solved
TypeScript 5.8. I have the standard recursive path type over a config object:
type Path<T> = T extends object
? { [K in keyof T & string]:
T[K] extends object ? K | `${K}.${Path<T[K]>}` : K
}[keyof T & string]
: never
Worked fine while the config was four levels deep. I added one more level and now get(config, "services.api.http.server.port") gives me:
error TS2589: Type instantiation is excessively deep and possibly infinite.
The config has 9 top-level keys and nothing recursive in it, so it is not actually infinite. Is there a way to make this scale or is the whole approach a dead end?
@orm_tamsin · 2w ago · 3 replies
Not a dead end, but you need a depth counter. The compiler is not confused, it hit its instantiation budget, and it has no way to know your object bottoms out.
The thing to internalise is that depth is not the real cost, the cross product is. Nine top keys with seven children each with six each with five is roughly 1,890 distinct string literals, and every one of them is a template literal instantiation the checker has to materialise. Add a level and you multiply, not add.
Capping at 4 means anything deeper falls back to
neverfor the tail, which in practice you handle by acceptingstringpast that depth. Nobody has ever complained about not getting autocomplete at level six.Reply
Report
@wellhead_wanda · last wk.
That fixed it, and the editor went from three seconds of lag on that file to instant. The array exclusion mattered more than I expected too — I had a
plugins: []in there.Reply
Report
@seedstart_sim · last wk.
The array exclusion is doing a lot of quiet work in that snippet. Without it you enumerate
length,toString,flatMapand about thirty other members at every level an array appears, which is usually where these things go from slow to impossible.Reply
Report