Skip to content

Commit b7da98b

Browse files
Use intersection of member names to find largest overlap.
1 parent 6ae288f commit b7da98b

File tree

1 file changed

+19
-17
lines changed

1 file changed

+19
-17
lines changed

src/compiler/checker.ts

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11959,29 +11959,31 @@ namespace ts {
1195911959
}
1196011960

1196111961
function findMostOverlappyType(source: Type, unionTarget: UnionOrIntersectionType) {
11962-
if (!(source.flags & (TypeFlags.Object | TypeFlags.Intersection))) {
11963-
return undefined;
11964-
}
11965-
const sourceProperties = getPropertiesOfType(source);
11966-
let bestType;
11967-
let count = -1;
11962+
let bestMatch: Type | undefined;
11963+
let matchingCount = 0;
1196811964
for (const target of unionTarget.types) {
11969-
if (!(target.flags & (TypeFlags.Object | TypeFlags.Intersection))) {
11970-
continue;
11965+
const overlap = getIntersectionType([getIndexType(source), getIndexType(target)]);
11966+
if (overlap.flags & TypeFlags.Index) {
11967+
// perfect overlap of keys
11968+
bestMatch = target;
11969+
matchingCount = Infinity;
1197111970
}
11972-
11973-
let currentCount = 0;
11974-
for (const prop of sourceProperties) {
11975-
if (getPropertyOfType(target, prop.escapedName)) {
11976-
currentCount++;
11971+
else if (overlap.flags & TypeFlags.Union) {
11972+
// Some subset overlap if we have only string literals.
11973+
// If we have a union of index types, it seems likely that we
11974+
// needed to elaborate between two generic mapped types anyway.
11975+
const len = length((overlap as UnionType).types);
11976+
if (len >= matchingCount) {
11977+
bestMatch = target;
11978+
matchingCount = len;
1197711979
}
1197811980
}
11979-
if (currentCount >= count) {
11980-
count = currentCount;
11981-
bestType = target;
11981+
else if (!(overlap.flags & TypeFlags.Never) && 1 >= matchingCount) {
11982+
bestMatch = target;
11983+
matchingCount = 1;
1198211984
}
1198311985
}
11984-
return bestType;
11986+
return bestMatch;
1198511987
}
1198611988

1198711989
// Keep this up-to-date with the same logic within `getApparentTypeOfContextualType`, since they should behave similarly

0 commit comments

Comments
 (0)