Bug Report
Intersection constructor types can repeatedly synthesize union/intersection properties with duplicate declaration arrays. In a diamond-like class/interface inheritance shape this causes quadratic/explosive declaration accumulation and can crash in addRange with:
RangeError: Invalid array length
Repro
A standalone compiler testcase is available here:
https://github.com/canonic-epicure/TypeScript/blob/fix-intersection-property-declarations-stacked/tests/cases/compiler/intersectionConstructorReductionCrash.ts
The shape is roughly:
- generated base classes use constructor-side intersections
- each constructor-side intersection includes previous mixin static sides via
Omit<typeof MixinN, "prototype">
- merged interfaces carry instance inheritance
- checking the base constructor type repeatedly synthesizes intersection properties
Observed
Before the fix, with the related base-type traversal fix applied, the testcase still crashes:
RangeError: Invalid array length
at Array.push
at addRange
at createUnionOrIntersectionProperty
at getUnionOrIntersectionProperty
at getPropertyOfUnionOrIntersectionType
at getPropertiesOfUnionOrIntersectionType
at getReducedType
at getReducedApparentType
at getSignaturesOfType
at isConstructorType
Elapsed time before crash: about 4 seconds.
This also affects Language Service / tsserver semantic diagnostics. In the original larger scenario, semanticDiagnosticsSync timed out before this fix. With the fix, the same scenario completed in about 18ms for initial diagnostics and about 7ms for edit diagnostics.
Expected
The compiler should not repeatedly accumulate duplicate declarations while synthesizing intersection properties.
Candidate fix
Deduplicate declarations when creating synthetic union/intersection properties:
canonic-epicure@7e6d30a
With the fix:
- direct
tsc check time: about 0.05s
- elapsed time: about 0.22s
- targeted compiler tests pass
Note
This fix is currently stacked on top of the related base-type traversal fix from:
#63555
Without that related fix, the same testcase no longer crashes after declaration deduplication, but still spends significant time in the separate base-type traversal path.
Bug Report
Intersection constructor types can repeatedly synthesize union/intersection properties with duplicate declaration arrays. In a diamond-like class/interface inheritance shape this causes quadratic/explosive declaration accumulation and can crash in
addRangewith:Repro
A standalone compiler testcase is available here:
https://github.com/canonic-epicure/TypeScript/blob/fix-intersection-property-declarations-stacked/tests/cases/compiler/intersectionConstructorReductionCrash.ts
The shape is roughly:
Omit<typeof MixinN, "prototype">Observed
Before the fix, with the related base-type traversal fix applied, the testcase still crashes:
Elapsed time before crash: about 4 seconds.
This also affects Language Service / tsserver semantic diagnostics. In the original larger scenario,
semanticDiagnosticsSynctimed out before this fix. With the fix, the same scenario completed in about 18ms for initial diagnostics and about 7ms for edit diagnostics.Expected
The compiler should not repeatedly accumulate duplicate declarations while synthesizing intersection properties.
Candidate fix
Deduplicate declarations when creating synthetic union/intersection properties:
canonic-epicure@7e6d30a
With the fix:
tsccheck time: about 0.05sNote
This fix is currently stacked on top of the related base-type traversal fix from:
#63555
Without that related fix, the same testcase no longer crashes after declaration deduplication, but still spends significant time in the separate base-type traversal path.