@@ -15036,6 +15036,26 @@ namespace ts {
15036
15036
}
15037
15037
}
15038
15038
15039
+ // Return true if the given expression is possibly a discriminant value. We limit the kinds of
15040
+ // expressions we check to those that don't depend on their contextual type in order not to cause
15041
+ // recursive (and possibly infinite) invocations of getContextualType.
15042
+ function isPossiblyDiscriminantValue(node: Expression): boolean {
15043
+ switch (node.kind) {
15044
+ case SyntaxKind.StringLiteral:
15045
+ case SyntaxKind.NumericLiteral:
15046
+ case SyntaxKind.NoSubstitutionTemplateLiteral:
15047
+ case SyntaxKind.TrueKeyword:
15048
+ case SyntaxKind.FalseKeyword:
15049
+ case SyntaxKind.NullKeyword:
15050
+ case SyntaxKind.Identifier:
15051
+ return true;
15052
+ case SyntaxKind.PropertyAccessExpression:
15053
+ case SyntaxKind.ParenthesizedExpression:
15054
+ return isPossiblyDiscriminantValue((<PropertyAccessExpression | ParenthesizedExpression>node).expression);
15055
+ }
15056
+ return false;
15057
+ }
15058
+
15039
15059
// Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily
15040
15060
// be "pushed" onto a node using the contextualType property.
15041
15061
function getApparentTypeOfContextualType(node: Expression): Type {
@@ -15049,8 +15069,8 @@ namespace ts {
15049
15069
propLoop: for (const prop of node.properties) {
15050
15070
if (!prop.symbol) continue;
15051
15071
if (prop.kind !== SyntaxKind.PropertyAssignment) continue;
15052
- if (isDiscriminantProperty(contextualType, prop.symbol.escapedName)) {
15053
- const discriminatingType = getTypeOfNode (prop.initializer);
15072
+ if (isPossiblyDiscriminantValue(prop.initializer) && isDiscriminantProperty(contextualType, prop.symbol.escapedName)) {
15073
+ const discriminatingType = checkExpression (prop.initializer);
15054
15074
for (const type of (contextualType as UnionType).types) {
15055
15075
const targetType = getTypeOfPropertyOfType(type, prop.symbol.escapedName);
15056
15076
if (targetType && checkTypeAssignableTo(discriminatingType, targetType, /*errorNode*/ undefined)) {
0 commit comments