Add initial support for 'in' typeguarding

This commit is contained in:
IdeaHunter
2017-04-19 00:08:54 +03:00
parent 7bb5fc22c2
commit 9c3c2adfb0
9 changed files with 1287 additions and 0 deletions

View File

@@ -749,6 +749,10 @@ namespace ts {
return expr1.kind === SyntaxKind.TypeOfExpression && isNarrowableOperand((<TypeOfExpression>expr1).expression) && expr2.kind === SyntaxKind.StringLiteral;
}
function isNarrowableInOperands(left: Expression, right: Expression) {
return left.kind === SyntaxKind.StringLiteral && isNarrowingExpression(right);
}
function isNarrowingBinaryExpression(expr: BinaryExpression) {
switch (expr.operatorToken.kind) {
case SyntaxKind.EqualsToken:
@@ -761,6 +765,8 @@ namespace ts {
isNarrowingTypeofOperands(expr.right, expr.left) || isNarrowingTypeofOperands(expr.left, expr.right);
case SyntaxKind.InstanceOfKeyword:
return isNarrowableOperand(expr.left);
case SyntaxKind.InKeyword:
return isNarrowableInOperands(expr.left, expr.right);
case SyntaxKind.CommaToken:
return isNarrowingExpression(expr.right);
}

View File

@@ -12722,6 +12722,14 @@ namespace ts {
return type;
}
function narrowByInKeyword(type: Type, literal: LiteralExpression, assumeTrue: boolean) {
if ((type.flags & (TypeFlags.Union | TypeFlags.Object)) || (type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType)) {
const propName = literal.text;
return filterType(type, t => !!getPropertyOfType(t, propName) === assumeTrue);
}
return type;
}
function narrowTypeByBinaryExpression(type: Type, expr: BinaryExpression, assumeTrue: boolean): Type {
switch (expr.operatorToken.kind) {
case SyntaxKind.EqualsToken:
@@ -12757,6 +12765,12 @@ namespace ts {
break;
case SyntaxKind.InstanceOfKeyword:
return narrowTypeByInstanceof(type, expr, assumeTrue);
case SyntaxKind.InKeyword:
const target = getReferenceCandidate(expr.right);
if (expr.left.kind === SyntaxKind.StringLiteral && isMatchingReference(reference, target)) {
return narrowByInKeyword(type, <LiteralExpression>expr.left, assumeTrue);
}
break;
case SyntaxKind.CommaToken:
return narrowType(type, expr.right, assumeTrue);
}