Skip to content

Commit 06fe1ed

Browse files
Use intersection of member names to find largest overlap.
1 parent 646e234 commit 06fe1ed

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
@@ -11963,29 +11963,31 @@ namespace ts {
1196311963
}
1196411964

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

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

0 commit comments

Comments
 (0)