@@ -195,6 +195,8 @@ namespace ts {
195
195
None = 0,
196
196
Source = 1 << 0,
197
197
Target = 1 << 1,
198
+
199
+ Both = Source | Target,
198
200
}
199
201
200
202
const enum MappedTypeModifiers {
@@ -15582,6 +15584,27 @@ namespace ts {
15582
15584
depth--;
15583
15585
if (result) {
15584
15586
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
+ }
15585
15608
// If result is definitely true, record all maybe keys as having succeeded
15586
15609
for (let i = maybeStart; i < maybeCount; i++) {
15587
15610
relation.set(maybeKeys[i], RelationComparisonResult.Succeeded | propagatingVarianceFlags);
@@ -15594,6 +15617,26 @@ namespace ts {
15594
15617
// assumptions it will also be false without assumptions)
15595
15618
relation.set(id, (reportErrors ? RelationComparisonResult.Reported : 0) | RelationComparisonResult.Failed | propagatingVarianceFlags);
15596
15619
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
+ }
15597
15640
}
15598
15641
return result;
15599
15642
}
0 commit comments