From d04f4a93a7fff465eaf2da93931f1949f6e49a22 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Fri, 9 Jun 2017 15:42:14 -0700 Subject: [PATCH] Do not check excess properties for multi-discriminant unions --- src/compiler/checker.ts | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 559d6ae71ba..f79e74746d4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9028,20 +9028,19 @@ namespace ts { } function findMatchingDiscriminantType(source: Type, target: UnionOrIntersectionType) { - const sourceProperties = getPropertiesOfObjectType(source); let match: Type; + const sourceProperties = getPropertiesOfObjectType(source); if (sourceProperties) { - for (const sourceProperty of sourceProperties) { - if (isDiscriminantProperty(target, sourceProperty.name)) { - const sourceType = getTypeOfSymbol(sourceProperty); - for (const type of target.types) { - const targetType = getTypeOfPropertyOfType(type, sourceProperty.name); - if (targetType && isRelatedTo(sourceType, targetType)) { - if (match) { - return undefined; - } - match = type; + const sourceProperty = findSingleDiscriminantProperty(sourceProperties, target); + if (sourceProperty) { + const sourceType = getTypeOfSymbol(sourceProperty); + for (const type of target.types) { + const targetType = getTypeOfPropertyOfType(type, sourceProperty.name); + if (targetType && isRelatedTo(sourceType, targetType)) { + if (match) { + return undefined; } + match = type; } } } @@ -10839,6 +10838,19 @@ namespace ts { return false; } + function findSingleDiscriminantProperty(sourceProperties: Symbol[], target: Type): Symbol | undefined { + let result: Symbol; + for (const sourceProperty of sourceProperties) { + if (isDiscriminantProperty(target, sourceProperty.name)) { + if (result) { + return undefined; + } + result = sourceProperty; + } + } + return result; + } + function isOrContainsMatchingReference(source: Node, target: Node) { return isMatchingReference(source, target) || containsMatchingReference(source, target); }