Skip to content

Commit 2d1639f

Browse files
committed
Property handle imcomplete control flow types in nested loops
1 parent 0006371 commit 2d1639f

File tree

1 file changed

+13
-2
lines changed

1 file changed

+13
-2
lines changed

src/compiler/checker.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8364,13 +8364,18 @@ namespace ts {
83648364
// each antecedent code path.
83658365
const antecedentTypes: Type[] = [];
83668366
let subtypeReduction = false;
8367+
let firstAntecedentType: FlowType;
83678368
flowLoopNodes[flowLoopCount] = flow;
83688369
flowLoopKeys[flowLoopCount] = key;
83698370
flowLoopTypes[flowLoopCount] = antecedentTypes;
83708371
for (const antecedent of flow.antecedents) {
83718372
flowLoopCount++;
8372-
const type = getTypeFromFlowType(getTypeAtFlowNode(antecedent));
8373+
const flowType = getTypeAtFlowNode(antecedent);
83738374
flowLoopCount--;
8375+
if (!firstAntecedentType) {
8376+
firstAntecedentType = flowType;
8377+
}
8378+
const type = getTypeFromFlowType(flowType);
83748379
// If we see a value appear in the cache it is a sign that control flow analysis
83758380
// was restarted and completed by checkExpressionCached. We can simply pick up
83768381
// the resulting type and bail out.
@@ -8393,7 +8398,13 @@ namespace ts {
83938398
break;
83948399
}
83958400
}
8396-
return cache[key] = getUnionType(antecedentTypes, subtypeReduction);
8401+
// The result is incomplete if the first antecedent (the non-looping control flow path)
8402+
// is incomplete.
8403+
const result = getUnionType(antecedentTypes, subtypeReduction);
8404+
if (isIncomplete(firstAntecedentType)) {
8405+
return createFlowType(result, /*incomplete*/ true);
8406+
}
8407+
return cache[key] = result;
83978408
}
83988409

83998410
function isMatchingReferenceDiscriminant(expr: Expression) {

0 commit comments

Comments
 (0)