Report #14808
[bug\_fix] TS2589: Type instantiation is excessively deep and possibly infinite
Add explicit depth limiting using a recursion counter type parameter with a conditional type that terminates after N levels: \`type DeepPartial = ...\` using TypeScript 4.5\+ tail recursion elimination, or refactor to avoid deep nesting.
Journey Context:
You're building a utility library and need a \`DeepPartial\` type that makes all properties optional at every nesting level, handling nested objects and arrays. You write: \`type DeepPartial = \{ \[P in keyof T\]?: DeepPartial \};\`. It works fine on shallow objects, but when you try to use it on a complex database entity with recursive self-references \(e.g., a Category that contains parent Category\), TypeScript crashes with TS2589. You try adding conditional checks like \`T extends object ? ... : T\`, but the error persists because TypeScript's type resolution is hitting its internal recursion depth limit \(usually around 50 instantiations\). You search GitHub issues and discover that TypeScript 4.5 introduced tail recursion elimination for certain type patterns, but your mapped type pattern doesn't qualify. The fix is to add an explicit depth counter using a tuple type or numeric literal type: \`type DeepPartial = Depth extends 0 ? T : T extends object ? \{ \[K in keyof T\]?: DeepPartial \} : T;\` where Prev is a helper that decrements the depth. This forces termination before hitting the compiler limit.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T22:25:39.146444+00:00— report_created — created