mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-07-01 11:42:55 -05:00
Properly reset type guards in loops
This commit is contained in:
@@ -7764,16 +7764,17 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isMatchingReference(source: Node, target: Node): boolean {
|
||||
if (source.kind === target.kind) {
|
||||
switch (source.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
return getResolvedSymbol(<Identifier>source) === getResolvedSymbol(<Identifier>target);
|
||||
case SyntaxKind.ThisKeyword:
|
||||
return true;
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
return (<PropertyAccessExpression>source).name.text === (<PropertyAccessExpression>target).name.text &&
|
||||
isMatchingReference((<PropertyAccessExpression>source).expression, (<PropertyAccessExpression>target).expression);
|
||||
}
|
||||
switch (source.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
return target.kind === SyntaxKind.Identifier && getResolvedSymbol(<Identifier>source) === getResolvedSymbol(<Identifier>target) ||
|
||||
(target.kind === SyntaxKind.VariableDeclaration || target.kind === SyntaxKind.BindingElement) &&
|
||||
getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(<Identifier>source)) === getSymbolOfNode(target);
|
||||
case SyntaxKind.ThisKeyword:
|
||||
return target.kind === SyntaxKind.ThisKeyword;
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
return target.kind === SyntaxKind.PropertyAccessExpression &&
|
||||
(<PropertyAccessExpression>source).name.text === (<PropertyAccessExpression>target).name.text &&
|
||||
isMatchingReference((<PropertyAccessExpression>source).expression, (<PropertyAccessExpression>target).expression);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -8031,6 +8032,12 @@ namespace ts {
|
||||
getInitialTypeOfBindingElement(<BindingElement>node);
|
||||
}
|
||||
|
||||
function getInitialOrAssignedType(node: VariableDeclaration | BindingElement | Expression) {
|
||||
return node.kind === SyntaxKind.VariableDeclaration || node.kind === SyntaxKind.BindingElement ?
|
||||
getInitialType(<VariableDeclaration | BindingElement>node) :
|
||||
getAssignedType(<Expression>node);
|
||||
}
|
||||
|
||||
function getReferenceCandidate(node: Expression): Expression {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
@@ -8153,19 +8160,9 @@ namespace ts {
|
||||
const node = flow.node;
|
||||
// Assignments only narrow the computed type if the declared type is a union type. Thus, we
|
||||
// only need to evaluate the assigned type if the declared type is a union type.
|
||||
if ((node.kind === SyntaxKind.VariableDeclaration || node.kind === SyntaxKind.BindingElement) &&
|
||||
reference.kind === SyntaxKind.Identifier &&
|
||||
getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(<Identifier>reference)) === getSymbolOfNode(node)) {
|
||||
return declaredType.flags & TypeFlags.Union ?
|
||||
getAssignmentReducedType(<UnionType>declaredType, getInitialType(<VariableDeclaration | BindingElement>node)) :
|
||||
declaredType;
|
||||
}
|
||||
// If the node is not a variable declaration or binding element, it is an identifier
|
||||
// or a dotted name that is the target of an assignment. If we have a match, reduce
|
||||
// the declared type by the assigned type.
|
||||
if (isMatchingReference(reference, node)) {
|
||||
return declaredType.flags & TypeFlags.Union ?
|
||||
getAssignmentReducedType(<UnionType>declaredType, getAssignedType(<Expression>node)) :
|
||||
getAssignmentReducedType(<UnionType>declaredType, getInitialOrAssignedType(node)) :
|
||||
declaredType;
|
||||
}
|
||||
// We didn't have a direct match. However, if the reference is a dotted name, this
|
||||
|
||||
Reference in New Issue
Block a user