@@ -7864,7 +7864,8 @@ namespace ts {
78647864 if (isNullOrUndefinedLiteral(expr.right)) {
78657865 return narrowTypeByNullCheck(type, expr, assumeTrue);
78667866 }
7867- if (expr.left.kind === SyntaxKind.TypeOfExpression && expr.right.kind === SyntaxKind.StringLiteral) {
7867+ if (expr.left.kind === SyntaxKind.TypeOfExpression && expr.right.kind === SyntaxKind.StringLiteral ||
7868+ expr.left.kind === SyntaxKind.StringLiteral && expr.right.kind === SyntaxKind.TypeOfExpression) {
78687869 return narrowTypeByTypeof(type, expr, assumeTrue);
78697870 }
78707871 break;
@@ -7897,12 +7898,12 @@ namespace ts {
78977898 function narrowTypeByTypeof(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type {
78987899 // We have '==', '!=', '====', or !==' operator with 'typeof xxx' on the left
78997900 // and string literal on the right
7900- const left = <TypeOfExpression>expr.left;
7901- const right = <LiteralExpression>expr.right;
7902- if (!isMatchingReference(reference, left .expression)) {
7901+ const typeOf = <TypeOfExpression>( expr.left.kind === SyntaxKind.TypeOfExpression ? expr.left : expr.right) ;
7902+ const literal = <LiteralExpression>( expr.right.kind === SyntaxKind.StringLiteral ? expr.right : expr.left) ;
7903+ if (!isMatchingReference(reference, typeOf .expression)) {
79037904 // For a reference of the form 'x.y', a 'typeof x === ...' type guard resets the
79047905 // narrowed type of 'y' to its declared type.
7905- if (containsMatchingReference(reference, left .expression)) {
7906+ if (containsMatchingReference(reference, typeOf .expression)) {
79067907 return declaredType;
79077908 }
79087909 return type;
@@ -7915,14 +7916,14 @@ namespace ts {
79157916 // We narrow a non-union type to an exact primitive type if the non-union type
79167917 // is a supertype of that primtive type. For example, type 'any' can be narrowed
79177918 // to one of the primitive types.
7918- const targetType = getProperty(typeofTypesByName, right .text);
7919+ const targetType = getProperty(typeofTypesByName, literal .text);
79197920 if (targetType && isTypeSubtypeOf(targetType, type)) {
79207921 return targetType;
79217922 }
79227923 }
79237924 const facts = assumeTrue ?
7924- getProperty(typeofEQFacts, right .text) || TypeFacts.TypeofEQHostObject :
7925- getProperty(typeofNEFacts, right .text) || TypeFacts.TypeofNEHostObject;
7925+ getProperty(typeofEQFacts, literal .text) || TypeFacts.TypeofEQHostObject :
7926+ getProperty(typeofNEFacts, literal .text) || TypeFacts.TypeofNEHostObject;
79267927 return getTypeWithFacts(type, facts);
79277928 }
79287929
0 commit comments