@@ -15459,6 +15459,7 @@ namespace ts {
15459
15459
let bivariant = false;
15460
15460
let propagationType: Type;
15461
15461
let inferenceCount = 0;
15462
+ let inferenceBlocked = false;
15462
15463
let allowComplexConstraintInference = true;
15463
15464
inferFromTypes(originalSource, originalTarget);
15464
15465
@@ -15655,6 +15656,7 @@ namespace ts {
15655
15656
if (source.flags & (TypeFlags.Object | TypeFlags.Intersection)) {
15656
15657
const key = source.id + "," + target.id;
15657
15658
if (visited && visited.get(key)) {
15659
+ inferenceBlocked = true;
15658
15660
return;
15659
15661
}
15660
15662
(visited || (visited = createMap<boolean>())).set(key, true);
@@ -15667,6 +15669,7 @@ namespace ts {
15667
15669
const symbol = isNonConstructorObject ? target.symbol : undefined;
15668
15670
if (symbol) {
15669
15671
if (contains(symbolStack, symbol)) {
15672
+ inferenceBlocked = true;
15670
15673
return;
15671
15674
}
15672
15675
(symbolStack || (symbolStack = [])).push(symbol);
@@ -15755,6 +15758,8 @@ namespace ts {
15755
15758
const sources = source.flags & TypeFlags.Union ? (<UnionType>source).types : [source];
15756
15759
const matched = new Array<boolean>(sources.length);
15757
15760
let typeVariableCount = 0;
15761
+ const saveInferenceBlocked = inferenceBlocked;
15762
+ inferenceBlocked = false;
15758
15763
// First infer to types that are not naked type variables. For each source type we
15759
15764
// track whether inferences were made from that particular type to some target.
15760
15765
for (const t of target.types) {
@@ -15771,14 +15776,15 @@ namespace ts {
15771
15776
}
15772
15777
// If there are naked type variables in the target, create a union of the source types
15773
15778
// from which no inferences have been made so far and infer from that union to each naked
15774
- // type variable. If there is more than one naked type variable, give lower priority to
15775
- // the inferences as they are less specific.
15779
+ // type variable. If there is more than one naked type variable, or if inference was blocked
15780
+ // (meaning we didn't explore the types fully), give lower priority to the inferences as
15781
+ // they are less specific.
15776
15782
if (typeVariableCount > 0) {
15777
15783
const unmatched = flatMap(sources, (s, i) => matched[i] ? undefined : s);
15778
15784
if (unmatched.length) {
15779
15785
const s = getUnionType(unmatched);
15780
15786
const savePriority = priority;
15781
- if (typeVariableCount > 1) {
15787
+ if (typeVariableCount > 1 || inferenceBlocked ) {
15782
15788
priority |= InferencePriority.NakedTypeVariable;
15783
15789
}
15784
15790
for (const t of target.types) {
@@ -15789,6 +15795,7 @@ namespace ts {
15789
15795
priority = savePriority;
15790
15796
}
15791
15797
}
15798
+ inferenceBlocked = saveInferenceBlocked;
15792
15799
}
15793
15800
15794
15801
function inferToMappedType(source: Type, target: MappedType, constraintType: Type): boolean {
0 commit comments