Skip to content

Commit 3e3b808

Browse files
committed
Properly reset type guards in loops
1 parent 878cf85 commit 3e3b808

File tree

1 file changed

+18
-21
lines changed

1 file changed

+18
-21
lines changed

src/compiler/checker.ts

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7764,16 +7764,17 @@ namespace ts {
77647764
}
77657765

77667766
function isMatchingReference(source: Node, target: Node): boolean {
7767-
if (source.kind === target.kind) {
7768-
switch (source.kind) {
7769-
case SyntaxKind.Identifier:
7770-
return getResolvedSymbol(<Identifier>source) === getResolvedSymbol(<Identifier>target);
7771-
case SyntaxKind.ThisKeyword:
7772-
return true;
7773-
case SyntaxKind.PropertyAccessExpression:
7774-
return (<PropertyAccessExpression>source).name.text === (<PropertyAccessExpression>target).name.text &&
7775-
isMatchingReference((<PropertyAccessExpression>source).expression, (<PropertyAccessExpression>target).expression);
7776-
}
7767+
switch (source.kind) {
7768+
case SyntaxKind.Identifier:
7769+
return target.kind === SyntaxKind.Identifier && getResolvedSymbol(<Identifier>source) === getResolvedSymbol(<Identifier>target) ||
7770+
(target.kind === SyntaxKind.VariableDeclaration || target.kind === SyntaxKind.BindingElement) &&
7771+
getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(<Identifier>source)) === getSymbolOfNode(target);
7772+
case SyntaxKind.ThisKeyword:
7773+
return target.kind === SyntaxKind.ThisKeyword;
7774+
case SyntaxKind.PropertyAccessExpression:
7775+
return target.kind === SyntaxKind.PropertyAccessExpression &&
7776+
(<PropertyAccessExpression>source).name.text === (<PropertyAccessExpression>target).name.text &&
7777+
isMatchingReference((<PropertyAccessExpression>source).expression, (<PropertyAccessExpression>target).expression);
77777778
}
77787779
return false;
77797780
}
@@ -8031,6 +8032,12 @@ namespace ts {
80318032
getInitialTypeOfBindingElement(<BindingElement>node);
80328033
}
80338034

8035+
function getInitialOrAssignedType(node: VariableDeclaration | BindingElement | Expression) {
8036+
return node.kind === SyntaxKind.VariableDeclaration || node.kind === SyntaxKind.BindingElement ?
8037+
getInitialType(<VariableDeclaration | BindingElement>node) :
8038+
getAssignedType(<Expression>node);
8039+
}
8040+
80348041
function getReferenceCandidate(node: Expression): Expression {
80358042
switch (node.kind) {
80368043
case SyntaxKind.ParenthesizedExpression:
@@ -8153,19 +8160,9 @@ namespace ts {
81538160
const node = flow.node;
81548161
// Assignments only narrow the computed type if the declared type is a union type. Thus, we
81558162
// only need to evaluate the assigned type if the declared type is a union type.
8156-
if ((node.kind === SyntaxKind.VariableDeclaration || node.kind === SyntaxKind.BindingElement) &&
8157-
reference.kind === SyntaxKind.Identifier &&
8158-
getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(<Identifier>reference)) === getSymbolOfNode(node)) {
8159-
return declaredType.flags & TypeFlags.Union ?
8160-
getAssignmentReducedType(<UnionType>declaredType, getInitialType(<VariableDeclaration | BindingElement>node)) :
8161-
declaredType;
8162-
}
8163-
// If the node is not a variable declaration or binding element, it is an identifier
8164-
// or a dotted name that is the target of an assignment. If we have a match, reduce
8165-
// the declared type by the assigned type.
81668163
if (isMatchingReference(reference, node)) {
81678164
return declaredType.flags & TypeFlags.Union ?
8168-
getAssignmentReducedType(<UnionType>declaredType, getAssignedType(<Expression>node)) :
8165+
getAssignmentReducedType(<UnionType>declaredType, getInitialOrAssignedType(node)) :
81698166
declaredType;
81708167
}
81718168
// We didn't have a direct match. However, if the reference is a dotted name, this

0 commit comments

Comments
 (0)