Skip to content

Commit 9b2d9cd

Browse files
committed
Fix issues uncovered by DT tests
1 parent 2541a5d commit 9b2d9cd

File tree

1 file changed

+33
-17
lines changed

1 file changed

+33
-17
lines changed

src/compiler/checker.ts

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13540,6 +13540,9 @@ namespace ts {
1354013540
if (relation !== identityRelation) {
1354113541
source = getApparentType(source);
1354213542
}
13543+
else if (isGenericMappedType(source)) {
13544+
return Ternary.False;
13545+
}
1354313546
if (getObjectFlags(source) & ObjectFlags.Reference && getObjectFlags(target) & ObjectFlags.Reference && (<TypeReference>source).target === (<TypeReference>target).target &&
1354413547
!(getObjectFlags(source) & ObjectFlags.MarkerType || getObjectFlags(target) & ObjectFlags.MarkerType)) {
1354513548
// We have type references to the same generic type, and the type references are not marker
@@ -15456,7 +15459,7 @@ namespace ts {
1545615459

1545715460
function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type, priority: InferencePriority = 0, contravariant = false) {
1545815461
let symbolStack: Symbol[];
15459-
let visited: Map<boolean>;
15462+
let visited: Map<number>;
1546015463
let bivariant = false;
1546115464
let propagationType: Type;
1546215465
let inferenceCount = 0;
@@ -15656,15 +15659,17 @@ namespace ts {
1565615659
}
1565715660
if (source.flags & (TypeFlags.Object | TypeFlags.Intersection)) {
1565815661
const key = source.id + "," + target.id;
15659-
if (visited && visited.get(key)) {
15660-
inferenceBlocked = true;
15662+
const visitCount = visited && visited.get(key);
15663+
if (visitCount !== undefined) {
15664+
inferenceCount += visitCount;
1566115665
return;
1566215666
}
15663-
(visited || (visited = createMap<boolean>())).set(key, true);
15667+
(visited || (visited = createMap<number>())).set(key, 0);
1566415668
// If we are already processing another target type with the same associated symbol (such as
1566515669
// an instantiation of the same generic type), we do not explore this target as it would yield
1566615670
// no further inferences. We exclude the static side of classes from this check since it shares
1566715671
// its symbol with the instance side which would lead to false positives.
15672+
const startCount = inferenceCount;
1566815673
const isNonConstructorObject = target.flags & TypeFlags.Object &&
1566915674
!(getObjectFlags(target) & ObjectFlags.Anonymous && target.symbol && target.symbol.flags & SymbolFlags.Class);
1567015675
const symbol = isNonConstructorObject ? target.symbol : undefined;
@@ -15680,14 +15685,21 @@ namespace ts {
1568015685
else {
1568115686
inferFromObjectTypes(source, target);
1568215687
}
15688+
visited.set(key, inferenceCount - startCount);
1568315689
}
1568415690
}
1568515691

1568615692
function inferFromTypesOnce(source: Type, target: Type) {
1568715693
const key = source.id + "," + target.id;
15688-
if (!visited || !visited.get(key)) {
15689-
(visited || (visited = createMap<boolean>())).set(key, true);
15694+
const count = visited && visited.get(key);
15695+
if (count !== undefined) {
15696+
inferenceCount += count;
15697+
}
15698+
else {
15699+
(visited || (visited = createMap<number>())).set(key, 0);
15700+
const startCount = inferenceCount;
1569015701
inferFromTypes(source, target);
15702+
visited.set(key, inferenceCount - startCount);
1569115703
}
1569215704
}
1569315705
}
@@ -15780,23 +15792,28 @@ namespace ts {
1578015792
// type variable. If there is more than one naked type variable, or if inference was blocked
1578115793
// (meaning we didn't explore the types fully), give lower priority to the inferences as
1578215794
// they are less specific.
15783-
if (typeVariableCount > 0) {
15795+
if (typeVariableCount === 1 && !inferenceBlocked) {
1578415796
const unmatched = flatMap(sources, (s, i) => matched[i] ? undefined : s);
1578515797
if (unmatched.length) {
1578615798
const s = getUnionType(unmatched);
15787-
const savePriority = priority;
15788-
if (typeVariableCount > 1 || inferenceBlocked) {
15789-
priority |= InferencePriority.NakedTypeVariable;
15790-
}
1579115799
for (const t of target.types) {
1579215800
if (getInferenceInfoForType(t)) {
1579315801
inferFromTypes(s, t);
1579415802
}
1579515803
}
15796-
priority = savePriority;
1579715804
}
1579815805
}
15799-
inferenceBlocked = saveInferenceBlocked;
15806+
inferenceBlocked = inferenceBlocked || saveInferenceBlocked;
15807+
if (typeVariableCount > 0) {
15808+
const savePriority = priority;
15809+
priority |= InferencePriority.NakedTypeVariable;
15810+
for (const t of target.types) {
15811+
if (getInferenceInfoForType(t)) {
15812+
inferFromTypes(source, t);
15813+
}
15814+
}
15815+
priority = savePriority;
15816+
}
1580015817
}
1580115818

1580215819
function inferToMappedType(source: Type, target: MappedType, constraintType: Type): boolean {
@@ -15958,14 +15975,13 @@ namespace ts {
1595815975
}
1595915976
}
1596015977

15961-
function isTypeReferenceToSameTarget(source: Type, target: Type) {
15962-
return !!(getObjectFlags(source) & ObjectFlags.Reference && getObjectFlags(target) & ObjectFlags.Reference &&
15963-
(<TypeReference>source).target === (<TypeReference>target).target);
15978+
function isMatchableType(type: Type) {
15979+
return !(type.flags & TypeFlags.Object) || !!(getObjectFlags(type) & ObjectFlags.Anonymous);
1596415980
}
1596515981

1596615982
function typeIdenticalToSomeType(type: Type, types: Type[]): boolean {
1596715983
for (const t of types) {
15968-
if (t === type || !isTypeReferenceToSameTarget(t, type) && isTypeIdenticalTo(t, type)) {
15984+
if (t === type || isMatchableType(t) && isMatchableType(type) && isTypeIdenticalTo(t, type)) {
1596915985
return true;
1597015986
}
1597115987
}

0 commit comments

Comments
 (0)