Filter primitives from union when checking for mismatched excess props if nonprimitive type is present (#31708)

* Filter primitives from union when checking for mismatched excess props if nonprimitive type is present

* Use maybeTypeOfKind
This commit is contained in:
Wesley Wigham
2019-06-12 17:31:57 -07:00
committed by GitHub
parent a0d164f142
commit 74c6bc1f85
6 changed files with 130 additions and 2 deletions

View File

@@ -12600,8 +12600,8 @@ namespace ts {
result = typeRelatedToSomeType(getRegularTypeOfObjectLiteral(source), <UnionType>target, reportErrors && !(source.flags & TypeFlags.Primitive) && !(target.flags & TypeFlags.Primitive));
if (result && isPerformingExcessPropertyChecks) {
// Validate against excess props using the original `source`
const discriminantType = target.flags & TypeFlags.Union ? findMatchingDiscriminantType(source, target as UnionType) : undefined;
if (!propertiesRelatedTo(source, discriminantType || target, reportErrors, /*excludedProperties*/ undefined)) {
const discriminantType = findMatchingDiscriminantType(source, target as UnionType) || filterPrimitivesIfContainsNonPrimitive(target as UnionType);
if (!propertiesRelatedTo(source, discriminantType, reportErrors, /*excludedProperties*/ undefined)) {
return Ternary.False;
}
}
@@ -12872,6 +12872,16 @@ namespace ts {
return bestMatch;
}
function filterPrimitivesIfContainsNonPrimitive(type: UnionType) {
if (maybeTypeOfKind(type, TypeFlags.NonPrimitive)) {
const result = filterType(type, t => !(t.flags & TypeFlags.Primitive));
if (!(result.flags & TypeFlags.Never)) {
return result;
}
}
return type;
}
// 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 && source.flags & (TypeFlags.Intersection | TypeFlags.Object)) {