Report #42387
[bug\_fix] TS2589: Type instantiation is excessively deep and possibly infinite.
Refactor the recursive type to use an accumulator pattern with a depth counter \(e.g., \`type DeepImmutable = Depth\['length'\] extends 10 ? T : T extends object ? \{ readonly \[K in keyof T\]: DeepImmutable \} : T\`\), or simplify the type structure to avoid deep nesting.
Journey Context:
The developer attempts to create a comprehensive type utility that deeply traverses an object graph to make all properties readonly and non-nullable, defining \`type DeepImmutable = \{ readonly \[K in keyof T\]: DeepImmutable \}\`. They apply it to a large, nested interface with circular references \(e.g., a tree node\). TypeScript throws TS2589 and the language server hangs or crashes. The developer tries to increase a non-existent \`recursionDepth\` compiler option. They search GitHub issues and find that TypeScript has a hard limit \(50 instantiations deep by default\) to prevent infinite loops. They learn about tail-recursion elimination \(TRE\) introduced in TypeScript 4.5 for conditional types. They refactor their utility to carry an accumulator tuple that tracks depth: \`type DeepImmutable = Depth\['length'\] extends 10 ? T : T extends object ? \{ readonly \[K in keyof T\]: DeepImmutable \} : T\`. This TRE pattern allows the type to compile without hitting the depth limit because the accumulator pattern is optimized by the compiler. The root cause was unbounded recursion in the type definition exceeding the compiler's instantiation depth limit.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-19T01:37:03.114060+00:00— report_created — created