mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-10 18:04:18 -05:00
Support typeof and instanceof
This commit is contained in:
@@ -856,9 +856,8 @@ namespace ts {
|
||||
function isNarrowableReference(expr: Expression): boolean {
|
||||
return expr.kind === SyntaxKind.Identifier || expr.kind === SyntaxKind.ThisKeyword || expr.kind === SyntaxKind.SuperKeyword ||
|
||||
(isPropertyAccessExpression(expr) || isNonNullExpression(expr) || isParenthesizedExpression(expr)) && isNarrowableReference(expr.expression) ||
|
||||
isElementAccessExpression(expr) &&
|
||||
isStringOrNumericLiteralLike(expr.argumentExpression) &&
|
||||
isNarrowableReference(expr.expression);
|
||||
isElementAccessExpression(expr) && isStringOrNumericLiteralLike(expr.argumentExpression) && isNarrowableReference(expr.expression) ||
|
||||
isOptionalChain(expr);
|
||||
}
|
||||
|
||||
function hasNarrowableArgument(expr: CallExpression) {
|
||||
|
||||
@@ -19360,7 +19360,7 @@ namespace ts {
|
||||
if (isMatchingReference(reference, right)) {
|
||||
return narrowTypeByEquality(type, operator, left, assumeTrue);
|
||||
}
|
||||
if (assumeTrue && (operator === SyntaxKind.EqualsEqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken)) {
|
||||
if (assumeTrue && strictNullChecks) {
|
||||
if (optionalChainContainsReference(left, reference)) {
|
||||
type = narrowTypeByOptionalChainContainment(type, operator, right);
|
||||
}
|
||||
@@ -19397,7 +19397,9 @@ namespace ts {
|
||||
// the type of obj if (a) the operator is === and the type of value doesn't include undefined or (b) the
|
||||
// operator is !== and the type of value is undefined.
|
||||
const valueType = getTypeOfExpression(value);
|
||||
return operator === SyntaxKind.EqualsEqualsEqualsToken && !(getTypeFacts(valueType) & TypeFacts.EQUndefined) ||
|
||||
return operator === SyntaxKind.EqualsEqualsToken && !(getTypeFacts(valueType) & TypeFacts.EQUndefinedOrNull) ||
|
||||
operator === SyntaxKind.EqualsEqualsEqualsToken && !(getTypeFacts(valueType) & TypeFacts.EQUndefined) ||
|
||||
operator === SyntaxKind.ExclamationEqualsToken && valueType.flags & TypeFlags.Nullable ||
|
||||
operator === SyntaxKind.ExclamationEqualsEqualsToken && valueType.flags & TypeFlags.Undefined ?
|
||||
getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull) : type;
|
||||
}
|
||||
@@ -19452,6 +19454,10 @@ namespace ts {
|
||||
// We have '==', '!=', '===', or !==' operator with 'typeof xxx' and string literal operands
|
||||
const target = getReferenceCandidate(typeOfExpr.expression);
|
||||
if (!isMatchingReference(reference, target)) {
|
||||
if (assumeTrue && (operator === SyntaxKind.EqualsEqualsToken || operator === SyntaxKind.EqualsEqualsEqualsToken) &&
|
||||
strictNullChecks && optionalChainContainsReference(target, reference)) {
|
||||
return getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull);
|
||||
}
|
||||
// For a reference of the form 'x.y', a 'typeof x === ...' type guard resets the
|
||||
// narrowed type of 'y' to its declared type.
|
||||
if (containsMatchingReference(reference, target)) {
|
||||
@@ -19633,6 +19639,9 @@ namespace ts {
|
||||
function narrowTypeByInstanceof(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type {
|
||||
const left = getReferenceCandidate(expr.left);
|
||||
if (!isMatchingReference(reference, left)) {
|
||||
if (assumeTrue && strictNullChecks && optionalChainContainsReference(left, reference)) {
|
||||
return getTypeWithFacts(type, TypeFacts.NEUndefinedOrNull);
|
||||
}
|
||||
// For a reference of the form 'x.y', an 'x instanceof T' type guard resets the
|
||||
// narrowed type of 'y' to its declared type. We do this because preceding 'x.y'
|
||||
// references might reference a different 'y' property. However, we make an exception
|
||||
|
||||
Reference in New Issue
Block a user