@@ -19360,7 +19360,7 @@ namespace ts {
1936019360 if (isMatchingReference(reference, right)) {
1936119361 return narrowTypeByEquality(type, operator, left, assumeTrue);
1936219362 }
19363- if (assumeTrue && (operator === SyntaxKind.EqualsEqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken) ) {
19363+ if (assumeTrue && strictNullChecks ) {
1936419364 if (optionalChainContainsReference(left, reference)) {
1936519365 type = narrowTypeByOptionalChainContainment(type, operator, right);
1936619366 }
@@ -19397,7 +19397,9 @@ namespace ts {
1939719397 // the type of obj if (a) the operator is === and the type of value doesn't include undefined or (b) the
1939819398 // operator is !== and the type of value is undefined.
1939919399 const valueType = getTypeOfExpression(value);
19400- return operator === SyntaxKind.EqualsEqualsEqualsToken && !(getTypeFacts(valueType) & TypeFacts.EQUndefined) ||
19400+ return operator === SyntaxKind.EqualsEqualsToken && !(getTypeFacts(valueType) & TypeFacts.EQUndefinedOrNull) ||
19401+ operator === SyntaxKind.EqualsEqualsEqualsToken && !(getTypeFacts(valueType) & TypeFacts.EQUndefined) ||
19402+ operator === SyntaxKind.ExclamationEqualsToken && valueType.flags & TypeFlags.Nullable ||
1940119403 operator === SyntaxKind.ExclamationEqualsEqualsToken && valueType.flags & TypeFlags.Undefined ?
1940219404 getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull) : type;
1940319405 }
@@ -19452,6 +19454,10 @@ namespace ts {
1945219454 // We have '==', '!=', '===', or !==' operator with 'typeof xxx' and string literal operands
1945319455 const target = getReferenceCandidate(typeOfExpr.expression);
1945419456 if (!isMatchingReference(reference, target)) {
19457+ if (assumeTrue && (operator === SyntaxKind.EqualsEqualsToken || operator === SyntaxKind.EqualsEqualsEqualsToken) &&
19458+ strictNullChecks && optionalChainContainsReference(target, reference)) {
19459+ return getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull);
19460+ }
1945519461 // For a reference of the form 'x.y', a 'typeof x === ...' type guard resets the
1945619462 // narrowed type of 'y' to its declared type.
1945719463 if (containsMatchingReference(reference, target)) {
@@ -19633,6 +19639,9 @@ namespace ts {
1963319639 function narrowTypeByInstanceof(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type {
1963419640 const left = getReferenceCandidate(expr.left);
1963519641 if (!isMatchingReference(reference, left)) {
19642+ if (assumeTrue && strictNullChecks && optionalChainContainsReference(left, reference)) {
19643+ return getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull);
19644+ }
1963619645 // For a reference of the form 'x.y', an 'x instanceof T' type guard resets the
1963719646 // narrowed type of 'y' to its declared type. We do this because preceding 'x.y'
1963819647 // references might reference a different 'y' property. However, we make an exception
0 commit comments