@@ -19360,7 +19360,7 @@ namespace ts {
19360
19360
if (isMatchingReference(reference, right)) {
19361
19361
return narrowTypeByEquality(type, operator, left, assumeTrue);
19362
19362
}
19363
- if (assumeTrue && (operator === SyntaxKind.EqualsEqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken) ) {
19363
+ if (assumeTrue && strictNullChecks ) {
19364
19364
if (optionalChainContainsReference(left, reference)) {
19365
19365
type = narrowTypeByOptionalChainContainment(type, operator, right);
19366
19366
}
@@ -19397,7 +19397,9 @@ namespace ts {
19397
19397
// the type of obj if (a) the operator is === and the type of value doesn't include undefined or (b) the
19398
19398
// operator is !== and the type of value is undefined.
19399
19399
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 ||
19401
19403
operator === SyntaxKind.ExclamationEqualsEqualsToken && valueType.flags & TypeFlags.Undefined ?
19402
19404
getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull) : type;
19403
19405
}
@@ -19452,6 +19454,10 @@ namespace ts {
19452
19454
// We have '==', '!=', '===', or !==' operator with 'typeof xxx' and string literal operands
19453
19455
const target = getReferenceCandidate(typeOfExpr.expression);
19454
19456
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
+ }
19455
19461
// For a reference of the form 'x.y', a 'typeof x === ...' type guard resets the
19456
19462
// narrowed type of 'y' to its declared type.
19457
19463
if (containsMatchingReference(reference, target)) {
@@ -19633,6 +19639,9 @@ namespace ts {
19633
19639
function narrowTypeByInstanceof(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type {
19634
19640
const left = getReferenceCandidate(expr.left);
19635
19641
if (!isMatchingReference(reference, left)) {
19642
+ if (assumeTrue && strictNullChecks && optionalChainContainsReference(left, reference)) {
19643
+ return getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull);
19644
+ }
19636
19645
// For a reference of the form 'x.y', an 'x instanceof T' type guard resets the
19637
19646
// narrowed type of 'y' to its declared type. We do this because preceding 'x.y'
19638
19647
// references might reference a different 'y' property. However, we make an exception
0 commit comments