Skip to content

Commit 1b46016

Browse files
committed
Cache multiple relationship comparisons based on one relationship comparison result
1 parent 2cc5856 commit 1b46016

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

src/compiler/checker.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,8 @@ namespace ts {
195195
None = 0,
196196
Source = 1 << 0,
197197
Target = 1 << 1,
198+
199+
Both = Source | Target,
198200
}
199201

200202
const enum MappedTypeModifiers {
@@ -15582,6 +15584,27 @@ namespace ts {
1558215584
depth--;
1558315585
if (result) {
1558415586
if (result === Ternary.True || depth === 0) {
15587+
// IntersectionState.Target _disables_ excess and common property checking on the target
15588+
// IntersectionState.Source _disables_ inferable index relating on the source
15589+
// This means if a type is assignable with none of these set, it should be assignable with either
15590+
// or both set
15591+
if (intersectionState === IntersectionState.None) {
15592+
const keys = [
15593+
getRelationKey(source, target, IntersectionState.Both, relation),
15594+
getRelationKey(source, target, IntersectionState.Target, relation),
15595+
getRelationKey(source, target, IntersectionState.Source, relation)
15596+
];
15597+
for (const k of keys) {
15598+
if (relation.has(k)) continue;
15599+
relation.set(k, RelationComparisonResult.Succeeded | propagatingVarianceFlags);
15600+
}
15601+
}
15602+
else if (intersectionState !== IntersectionState.Both) {
15603+
const k = getRelationKey(source, target, IntersectionState.Both, relation);
15604+
if (!relation.has(k)) {
15605+
relation.set(k, RelationComparisonResult.Succeeded | propagatingVarianceFlags);
15606+
}
15607+
}
1558515608
// If result is definitely true, record all maybe keys as having succeeded
1558615609
for (let i = maybeStart; i < maybeCount; i++) {
1558715610
relation.set(maybeKeys[i], RelationComparisonResult.Succeeded | propagatingVarianceFlags);
@@ -15594,6 +15617,26 @@ namespace ts {
1559415617
// assumptions it will also be false without assumptions)
1559515618
relation.set(id, (reportErrors ? RelationComparisonResult.Reported : 0) | RelationComparisonResult.Failed | propagatingVarianceFlags);
1559615619
maybeCount = maybeStart;
15620+
15621+
// similarly to the success case, if a type _is not_ assignable with IntersectionState.Both set,
15622+
// then it's impossible for it to have been assignable in any of the stronger modes, too
15623+
if (intersectionState === IntersectionState.Both) {
15624+
const keys = [
15625+
getRelationKey(source, target, IntersectionState.None, relation),
15626+
getRelationKey(source, target, IntersectionState.Target, relation),
15627+
getRelationKey(source, target, IntersectionState.Source, relation)
15628+
];
15629+
for (const k of keys) {
15630+
if (relation.has(k)) continue;
15631+
relation.set(k, RelationComparisonResult.Failed | propagatingVarianceFlags);
15632+
}
15633+
}
15634+
else if (intersectionState !== IntersectionState.None) {
15635+
const k = getRelationKey(source, target, IntersectionState.None, relation);
15636+
if (!relation.has(k)) {
15637+
relation.set(k, RelationComparisonResult.Failed | propagatingVarianceFlags);
15638+
}
15639+
}
1559715640
}
1559815641
return result;
1559915642
}

0 commit comments

Comments
 (0)