@@ -20265,12 +20265,6 @@ namespace ts {
2026520265 if (right.kind === SyntaxKind.TypeOfExpression && isStringLiteralLike(left)) {
2026620266 return narrowTypeByTypeof(type, <TypeOfExpression>right, operator, left, assumeTrue);
2026720267 }
20268- if (isConstructorAccessExpression(left)) {
20269- return narrowTypeByConstructor(type, left, operator, right, assumeTrue);
20270- }
20271- if (isConstructorAccessExpression(right)) {
20272- return narrowTypeByConstructor(type, right, operator, left, assumeTrue);
20273- }
2027420268 if (isMatchingReference(reference, left)) {
2027520269 return narrowTypeByEquality(type, operator, right, assumeTrue);
2027620270 }
@@ -20291,6 +20285,12 @@ namespace ts {
2029120285 if (isMatchingReferenceDiscriminant(right, declaredType)) {
2029220286 return narrowTypeByDiscriminant(type, <AccessExpression>right, t => narrowTypeByEquality(t, operator, left, assumeTrue));
2029320287 }
20288+ if (isMatchingConstructorReference(left)) {
20289+ return narrowTypeByConstructor(type, operator, right, assumeTrue);
20290+ }
20291+ if (isMatchingConstructorReference(right)) {
20292+ return narrowTypeByConstructor(type, operator, left, assumeTrue);
20293+ }
2029420294 break;
2029520295 case SyntaxKind.InstanceOfKeyword:
2029620296 return narrowTypeByInstanceof(type, expr, assumeTrue);
@@ -20564,17 +20564,18 @@ namespace ts {
2056420564 return getTypeWithFacts(mapType(type, narrowTypeForTypeofSwitch(impliedType)), switchFacts);
2056520565 }
2056620566
20567- function narrowTypeByConstructor(type: Type, constructorAccessExpr: AccessExpression, operator: SyntaxKind, identifier: Expression, assumeTrue: boolean): Type {
20567+ function isMatchingConstructorReference(expr: Expression) {
20568+ return (isPropertyAccessExpression(expr) && idText(expr.name) === "constructor" ||
20569+ isElementAccessExpression(expr) && isStringLiteralLike(expr.argumentExpression) && expr.argumentExpression.text === "constructor") &&
20570+ isMatchingReference(reference, expr.expression);
20571+ }
20572+
20573+ function narrowTypeByConstructor(type: Type, operator: SyntaxKind, identifier: Expression, assumeTrue: boolean): Type {
2056820574 // Do not narrow when checking inequality.
2056920575 if (assumeTrue ? (operator !== SyntaxKind.EqualsEqualsToken && operator !== SyntaxKind.EqualsEqualsEqualsToken) : (operator !== SyntaxKind.ExclamationEqualsToken && operator !== SyntaxKind.ExclamationEqualsEqualsToken)) {
2057020576 return type;
2057120577 }
2057220578
20573- // In the case of `x.y`, a `x.constructor === T` type guard resets the narrowed type of `y` to its declared type.
20574- if (!isMatchingReference(reference, constructorAccessExpr.expression)) {
20575- return declaredType;
20576- }
20577-
2057820579 // Get the type of the constructor identifier expression, if it is not a function then do not narrow.
2057920580 const identifierType = getTypeOfExpression(identifier);
2058020581 if (!isFunctionType(identifierType) && !isConstructorType(identifierType)) {
0 commit comments