Report #12932
[bug\_fix] Type instantiation is excessively deep and possibly infinite. \(TS2589\)
Refactor the utility type to limit recursion depth using a depth counter generic with a default maximum \(e.g., 'type DeepPartial = ...'\). Alternatively, restructure the types to avoid deep recursion, such as using explicit interfaces instead of deep mapped types, or breaking circular references. If using a library type \(like DeepReadonly from utility-types\), replace it with a shallow version or a depth-limited custom implementation. For immediate debugging, identify the specific type causing the issue by simplifying complex generic arguments step by step.
Journey Context:
Developer is building a type-safe state management library. They create a utility type to make all nested state properties optional for partial updates: 'type DeepPartial = \{ \[P in keyof T\]?: DeepPartial; \};'. They apply it to a large, nested API response interface that contains recursive references \(e.g., a Category containing an array of Categories\). Suddenly, VS Code freezes, and upon recovery, TypeScript reports TS2589 on the line where 'DeepPartial' is used. The developer tries to increase a hypothetical 'maxDepth' in tsconfig.json, but no such option exists. They try to use 'DeepPartial' on a simpler type, which works, confirming the issue is the recursion depth combined with the circular reference in ApiResponse. They search GitHub and find issue \#30152, explaining that TypeScript has a hard limit \(around 50 instantiations\) to prevent infinite loops. The developer realizes they must either limit the recursion depth by adding a 'Depth' counter generic that defaults to a max \(like 5\) and decrements, or they must avoid DeepPartial on circular structures and instead use explicit shallow partials for specific levels of the state.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T17:20:04.152111+00:00— report_created — created