@@ -15307,6 +15307,26 @@ namespace ts {
15307
15307
}
15308
15308
}
15309
15309
15310
+ // Return true if the given expression is possibly a discriminant value. We limit the kinds of
15311
+ // expressions we check to those that don't depend on their contextual type in order not to cause
15312
+ // recursive (and possibly infinite) invocations of getContextualType.
15313
+ function isPossiblyDiscriminantValue(node: Expression): boolean {
15314
+ switch (node.kind) {
15315
+ case SyntaxKind.StringLiteral:
15316
+ case SyntaxKind.NumericLiteral:
15317
+ case SyntaxKind.NoSubstitutionTemplateLiteral:
15318
+ case SyntaxKind.TrueKeyword:
15319
+ case SyntaxKind.FalseKeyword:
15320
+ case SyntaxKind.NullKeyword:
15321
+ case SyntaxKind.Identifier:
15322
+ return true;
15323
+ case SyntaxKind.PropertyAccessExpression:
15324
+ case SyntaxKind.ParenthesizedExpression:
15325
+ return isPossiblyDiscriminantValue((<PropertyAccessExpression | ParenthesizedExpression>node).expression);
15326
+ }
15327
+ return false;
15328
+ }
15329
+
15310
15330
// Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily
15311
15331
// be "pushed" onto a node using the contextualType property.
15312
15332
function getApparentTypeOfContextualType(node: Expression): Type {
@@ -15320,8 +15340,8 @@ namespace ts {
15320
15340
propLoop: for (const prop of node.properties) {
15321
15341
if (!prop.symbol) continue;
15322
15342
if (prop.kind !== SyntaxKind.PropertyAssignment) continue;
15323
- if (isDiscriminantProperty(contextualType, prop.symbol.escapedName)) {
15324
- const discriminatingType = getTypeOfNode (prop.initializer);
15343
+ if (isPossiblyDiscriminantValue(prop.initializer) && isDiscriminantProperty(contextualType, prop.symbol.escapedName)) {
15344
+ const discriminatingType = checkExpression (prop.initializer);
15325
15345
for (const type of (contextualType as UnionType).types) {
15326
15346
const targetType = getTypeOfPropertyOfType(type, prop.symbol.escapedName);
15327
15347
if (targetType && checkTypeAssignableTo(discriminatingType, targetType, /*errorNode*/ undefined)) {
0 commit comments