Report #4974
[bug\_fix] Type instantiation is excessively deep and possibly infinite. TS2589.
Restructure the recursive type to use tail-recursion elimination \(TRE\) available in TypeScript 4.5\+ by ensuring the recursive call is in the 'true' branch of a conditional type and returns immediately without further wrapping, OR add an explicit depth limiter type parameter \(e.g., 'Depth extends number = 5'\) that decrements until a base case \(0\) is reached to cap recursion. Root cause: TypeScript has a hard limit on type instantiation depth \(50 levels by default\) to prevent infinite loops during type evaluation. Recursive mapped types or deep object traversal that isn't tail-call optimized or artificially limited exceeds this limit.
Journey Context:
You're building a generic DeepPartial utility type for a complex Redux state tree. You define: type DeepPartial = \{ \[P in keyof T\]?: DeepPartial; \}. You apply it to a large interface 'AppState' that has 8\+ levels of nested objects including circular references \(e.g., Node \{ children: Node\[\] \}\). Suddenly VS Code hangs, the TypeScript server crashes, or you get error TS2589: 'Type instantiation is excessively deep and possibly infinite.' You try to increase Node.js memory with --max-old-space-size but it doesn't help. You search the error and find GitHub issue \#30118 discussing recursion limits. You read the TypeScript 4.5 release notes about Tail Recursion Elimination on Conditional Types. You realize your mapped type isn't tail-recursive because it wraps the recursive result in an object literal structure \{ \[K\]: RecursiveCall \}. You rewrite the type using a depth limiter pattern: type DeepPartial = Depth extends 0 ? T : T extends object ? \{ \[K in keyof T\]?: DeepPartial> \} : T; where Prev is a utility type that maps 3->2, 2->1, 1->0. This caps the recursion at 3 levels. The error disappears, compilation is fast, and you still get the deep partial typing you need for the top levels of your state tree.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-15T20:23:47.277413+00:00— report_created — created