Try to find object/intersection types with the most overlap when failing assignability against unions.

This commit is contained in:
Daniel Rosenwasser 2018-09-13 17:49:09 -07:00
parent c8ae5b5acf
commit 7e07eef8bb

View File

@ -11921,7 +11921,8 @@ namespace ts {
findMatchingDiscriminantType(source, target) ||
findMatchingTypeReferenceOrTypeAliasReference(source, target) ||
findBestTypeForObjectLiteral(source, target) ||
findBestTypeForInvokable(source, target);
findBestTypeForInvokable(source, target) ||
findMostOverlappyType(source, target);
isRelatedTo(source, bestMatchingType || targetTypes[targetTypes.length - 1], /*reportErrors*/ true);
}
@ -11961,6 +11962,32 @@ namespace ts {
}
}
function findMostOverlappyType(source: Type, unionTarget: UnionOrIntersectionType) {
if (!(source.flags & (TypeFlags.Object | TypeFlags.Intersection))) {
return undefined;
}
const sourceProperties = getPropertiesOfType(source);
let bestType;
let count = -1;
for (const target of unionTarget.types) {
if (!(target.flags & (TypeFlags.Object | TypeFlags.Intersection))) {
continue;
}
let currentCount = 0;
for (const prop of sourceProperties) {
if (getPropertyOfType(target, prop.escapedName)) {
currentCount++;
}
}
if (currentCount >= count) {
count = currentCount;
bestType = target;
}
}
return bestType;
}
// Keep this up-to-date with the same logic within `getApparentTypeOfContextualType`, since they should behave similarly
function findMatchingDiscriminantType(source: Type, target: Type) {
if (target.flags & TypeFlags.Union) {