Skip to content

Commit 87f55fa

Browse files
committed
Only evaluate assigned type when declared type is a union type
1 parent b5104cb commit 87f55fa

File tree

1 file changed

+10
-4
lines changed

1 file changed

+10
-4
lines changed

src/compiler/checker.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7343,9 +7343,9 @@ namespace ts {
73437343
// Remove those constituent types of declaredType to which no constituent type of assignedType is assignable.
73447344
// For example, when a variable of type number | string | boolean is assigned a value of type number | boolean,
73457345
// we remove type string.
7346-
function getAssignmentReducedType(declaredType: Type, assignedType: Type) {
7346+
function getAssignmentReducedType(declaredType: UnionType, assignedType: Type) {
73477347
if (declaredType !== assignedType && declaredType.flags & TypeFlags.Union) {
7348-
const reducedTypes = filter((<UnionType>declaredType).types, t => typeMaybeAssignableTo(assignedType, t));
7348+
const reducedTypes = filter(declaredType.types, t => typeMaybeAssignableTo(assignedType, t));
73497349
if (reducedTypes.length) {
73507350
return reducedTypes.length === 1 ? reducedTypes[0] : getUnionType(reducedTypes);
73517351
}
@@ -7573,16 +7573,22 @@ namespace ts {
75737573

75747574
function getTypeAtFlowAssignment(flow: FlowAssignment) {
75757575
const node = flow.node;
7576+
// Assignments only narrow the computed type if the declared type is a union type. Thus, we
7577+
// only need to evaluate the assigned type if the declared type is a union type.
75767578
if ((node.kind === SyntaxKind.VariableDeclaration || node.kind === SyntaxKind.BindingElement) &&
75777579
reference.kind === SyntaxKind.Identifier &&
75787580
getResolvedSymbol(<Identifier>reference) === getSymbolOfNode(node)) {
7579-
return getAssignmentReducedType(declaredType, getInitialType(<VariableDeclaration | BindingElement>node));
7581+
return declaredType.flags & TypeFlags.Union ?
7582+
getAssignmentReducedType(<UnionType>declaredType, getInitialType(<VariableDeclaration | BindingElement>node)) :
7583+
declaredType;
75807584
}
75817585
// If the node is not a variable declaration or binding element, it is an identifier
75827586
// or a dotted name that is the target of an assignment. If we have a match, reduce
75837587
// the declared type by the assigned type.
75847588
if (isMatchingReference(reference, node)) {
7585-
return getAssignmentReducedType(declaredType, getAssignedType(<Expression>node));
7589+
return declaredType.flags & TypeFlags.Union ?
7590+
getAssignmentReducedType(<UnionType>declaredType, getAssignedType(<Expression>node)) :
7591+
declaredType;
75867592
}
75877593
// We didn't have a direct match. However, if the reference is a dotted name, this
75887594
// may be an assignment to a left hand part of the reference. For example, for a

0 commit comments

Comments
 (0)