mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-15 20:25:23 -06:00
Allow primitive type guards with typeof on right
Previously, only type guards of the form `typeof x === 'string'` were allowed. Now you can write `'string' === typeof x`.
This commit is contained in:
parent
6b8109a501
commit
7c1b28f2cb
@ -612,7 +612,7 @@ namespace ts {
|
||||
if (isNarrowingExpression(expr.left) && (expr.right.kind === SyntaxKind.NullKeyword || expr.right.kind === SyntaxKind.Identifier)) {
|
||||
return true;
|
||||
}
|
||||
if (expr.left.kind === SyntaxKind.TypeOfExpression && isNarrowingExpression((<TypeOfExpression>expr.left).expression) && expr.right.kind === SyntaxKind.StringLiteral) {
|
||||
if (isTypeOfNarrowingBinaryExpression(expr)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -624,6 +624,20 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
function isTypeOfNarrowingBinaryExpression(expr: BinaryExpression) {
|
||||
let typeOf: Expression;
|
||||
if (expr.left.kind === SyntaxKind.StringLiteral) {
|
||||
typeOf = expr.right;
|
||||
}
|
||||
else if (expr.right.kind === SyntaxKind.StringLiteral) {
|
||||
typeOf = expr.left;
|
||||
}
|
||||
else {
|
||||
typeOf = undefined;;
|
||||
}
|
||||
return typeOf && typeOf.kind === SyntaxKind.TypeOfExpression && isNarrowingExpression((<TypeOfExpression>typeOf).expression);
|
||||
}
|
||||
|
||||
function createBranchLabel(): FlowLabel {
|
||||
return {
|
||||
flags: FlowFlags.BranchLabel,
|
||||
|
||||
@ -7864,7 +7864,8 @@ namespace ts {
|
||||
if (isNullOrUndefinedLiteral(expr.right)) {
|
||||
return narrowTypeByNullCheck(type, expr, assumeTrue);
|
||||
}
|
||||
if (expr.left.kind === SyntaxKind.TypeOfExpression && expr.right.kind === SyntaxKind.StringLiteral) {
|
||||
if (expr.left.kind === SyntaxKind.TypeOfExpression && expr.right.kind === SyntaxKind.StringLiteral ||
|
||||
expr.left.kind === SyntaxKind.StringLiteral && expr.right.kind === SyntaxKind.TypeOfExpression) {
|
||||
return narrowTypeByTypeof(type, expr, assumeTrue);
|
||||
}
|
||||
break;
|
||||
@ -7897,12 +7898,12 @@ namespace ts {
|
||||
function narrowTypeByTypeof(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type {
|
||||
// We have '==', '!=', '====', or !==' operator with 'typeof xxx' on the left
|
||||
// and string literal on the right
|
||||
const left = <TypeOfExpression>expr.left;
|
||||
const right = <LiteralExpression>expr.right;
|
||||
if (!isMatchingReference(reference, left.expression)) {
|
||||
const typeOf = <TypeOfExpression>(expr.left.kind === SyntaxKind.TypeOfExpression ? expr.left : expr.right);
|
||||
const literal = <LiteralExpression>(expr.right.kind === SyntaxKind.StringLiteral ? expr.right : expr.left);
|
||||
if (!isMatchingReference(reference, typeOf.expression)) {
|
||||
// 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, left.expression)) {
|
||||
if (containsMatchingReference(reference, typeOf.expression)) {
|
||||
return declaredType;
|
||||
}
|
||||
return type;
|
||||
@ -7915,14 +7916,14 @@ namespace ts {
|
||||
// We narrow a non-union type to an exact primitive type if the non-union type
|
||||
// is a supertype of that primtive type. For example, type 'any' can be narrowed
|
||||
// to one of the primitive types.
|
||||
const targetType = getProperty(typeofTypesByName, right.text);
|
||||
const targetType = getProperty(typeofTypesByName, literal.text);
|
||||
if (targetType && isTypeSubtypeOf(targetType, type)) {
|
||||
return targetType;
|
||||
}
|
||||
}
|
||||
const facts = assumeTrue ?
|
||||
getProperty(typeofEQFacts, right.text) || TypeFacts.TypeofEQHostObject :
|
||||
getProperty(typeofNEFacts, right.text) || TypeFacts.TypeofNEHostObject;
|
||||
getProperty(typeofEQFacts, literal.text) || TypeFacts.TypeofEQHostObject :
|
||||
getProperty(typeofNEFacts, literal.text) || TypeFacts.TypeofNEHostObject;
|
||||
return getTypeWithFacts(type, facts);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user