Skip to content

Commit 52dc9f2

Browse files
authored
No recursive intersection property checks (#37854)
* No recursive intersection property checks * Add comment
1 parent 6b1c102 commit 52dc9f2

File tree

1 file changed

+9
-2
lines changed

1 file changed

+9
-2
lines changed

src/compiler/checker.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ namespace ts {
196196
Source = 1 << 0,
197197
Target = 1 << 1,
198198
PropertyCheck = 1 << 2,
199+
InPropertyCheck = 1 << 3,
199200
}
200201

201202
const enum MappedTypeModifiers {
@@ -15245,6 +15246,7 @@ namespace ts {
1524515246
let overrideNextErrorInfo = 0; // How many `reportRelationError` calls should be skipped in the elaboration pyramid
1524615247
let lastSkippedInfo: [Type, Type] | undefined;
1524715248
let incompatibleStack: [DiagnosticMessage, (string | number)?, (string | number)?, (string | number)?, (string | number)?][] = [];
15249+
let inPropertyCheck = false;
1524815250

1524915251
Debug.assert(relation !== identityRelation || !errorNode, "no error reporting in identity checking");
1525015252

@@ -15680,10 +15682,15 @@ namespace ts {
1568015682
// function foo<T extends object>(x: { a?: string }, y: T & { a: boolean }) {
1568115683
// x = y; // Mismatched property in source intersection
1568215684
// }
15683-
if (result && (
15685+
//
15686+
// We suppress recursive intersection property checks because they can generate lots of work when relating
15687+
// recursive intersections that are structurally similar but not exactly identical. See #37854.
15688+
if (result && !inPropertyCheck && (
1568415689
target.flags & TypeFlags.Intersection && (isPerformingExcessPropertyChecks || isPerformingCommonPropertyChecks) ||
1568515690
isNonGenericObjectType(target) && source.flags & TypeFlags.Intersection && getApparentType(source).flags & TypeFlags.StructuredType && !some((<IntersectionType>source).types, t => !!(getObjectFlags(t) & ObjectFlags.NonInferrableType)))) {
15691+
inPropertyCheck = true;
1568615692
result &= recursiveTypeRelatedTo(source, target, reportErrors, IntersectionState.PropertyCheck);
15693+
inPropertyCheck = false;
1568715694
}
1568815695

1568915696
if (!result && reportErrors) {
@@ -15980,7 +15987,7 @@ namespace ts {
1598015987
if (overflow) {
1598115988
return Ternary.False;
1598215989
}
15983-
const id = getRelationKey(source, target, intersectionState, relation);
15990+
const id = getRelationKey(source, target, intersectionState | (inPropertyCheck ? IntersectionState.InPropertyCheck : 0), relation);
1598415991
const entry = relation.get(id);
1598515992
if (entry !== undefined) {
1598615993
if (reportErrors && entry & RelationComparisonResult.Failed && !(entry & RelationComparisonResult.Reported)) {

0 commit comments

Comments
 (0)