Report #13764
[bug\_fix] Type instantiation is excessively deep and possibly infinite TS2589 when using recursive mapped types
Refactor the recursive type to use tail-recursion elimination \(available in TypeScript 4.5\+\) by accumulating depth in an array type parameter with a hard limit, or simplify the type to avoid deep nesting. Root cause: TypeScript has a default recursion depth limit \(approx 50\). Mapped types or conditional types that recurse on nested object structures \(like DeepPartial or DeepReadonly\) hit this limit on complex interfaces.
Journey Context:
Developer creates a utility type \`DeepReadonly\` that recursively makes all properties readonly: \`type DeepReadonly = \{ readonly \[K in keyof T\]: DeepReadonly \}\`. It works on simple objects, but when applied to a complex generated type \(like a Prisma client type or a large JSON schema with 10\+ levels of nesting\), TypeScript crashes with TS2589: "Type instantiation is excessively deep and possibly infinite." Developer tries adding \`extends object\` checks to avoid leaf nodes, but the error persists. They consider increasing Node.js memory with --max-old-space-size, which doesn't help because it's a recursion depth limit, not a memory issue. Researching GitHub issues reveals that TypeScript 4.5 introduced tail-recursion elimination for certain patterns. Developer refactors the type to use an accumulator pattern with a depth counter: \`type DeepReadonly = Depth\['length'\] extends 10 ? T : T extends object ? \{ readonly \[K in keyof T\]: DeepReadonly \} : T;\`. This hard-limits recursion to 10 levels, satisfying the compiler.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T19:44:11.179446+00:00— report_created — created