@@ -19294,9 +19294,6 @@ namespace ts {
19294
19294
else if (containsMatchingReferenceDiscriminant(reference, expr)) {
19295
19295
type = declaredType;
19296
19296
}
19297
- else if (flow.clauseStart === flow.clauseEnd && isExhaustiveSwitchStatement(flow.switchStatement)) {
19298
- return unreachableNeverType;
19299
- }
19300
19297
}
19301
19298
return createFlowType(type, isIncomplete(flowType));
19302
19299
}
@@ -19305,13 +19302,19 @@ namespace ts {
19305
19302
const antecedentTypes: Type[] = [];
19306
19303
let subtypeReduction = false;
19307
19304
let seenIncomplete = false;
19305
+ let bypassFlow: FlowSwitchClause | undefined;
19308
19306
for (const antecedent of flow.antecedents!) {
19309
19307
if (antecedent.flags & FlowFlags.PreFinally && (<PreFinallyFlow>antecedent).lock.locked) {
19310
19308
// if flow correspond to branch from pre-try to finally and this branch is locked - this means that
19311
19309
// we initially have started following the flow outside the finally block.
19312
19310
// in this case we should ignore this branch.
19313
19311
continue;
19314
19312
}
19313
+ if (!bypassFlow && antecedent.flags & FlowFlags.SwitchClause && (<FlowSwitchClause>antecedent).clauseStart === (<FlowSwitchClause>antecedent).clauseEnd) {
19314
+ // The antecedent is the bypass branch of a potentially exhaustive switch statement.
19315
+ bypassFlow = <FlowSwitchClause>antecedent;
19316
+ continue;
19317
+ }
19315
19318
const flowType = getTypeAtFlowNode(antecedent);
19316
19319
const type = getTypeFromFlowType(flowType);
19317
19320
// If the type at a particular antecedent path is the declared type and the
@@ -19332,6 +19335,25 @@ namespace ts {
19332
19335
seenIncomplete = true;
19333
19336
}
19334
19337
}
19338
+ if (bypassFlow) {
19339
+ const flowType = getTypeAtFlowNode(bypassFlow.antecedent);
19340
+ const type = getTypeFromFlowType(flowType);
19341
+ // If the bypass flow contributes a type we haven't seen yet and the switch statement
19342
+ // isn't exhaustive, process the bypass flow type. Since exhaustiveness checks increase
19343
+ // the risk of circularities, we only want to perform them when they make a difference.
19344
+ if (!contains(antecedentTypes, type) && !isExhaustiveSwitchStatement(bypassFlow.switchStatement)) {
19345
+ if (type === declaredType && declaredType === initialType) {
19346
+ return type;
19347
+ }
19348
+ antecedentTypes.push(type);
19349
+ if (!isTypeSubsetOf(type, declaredType)) {
19350
+ subtypeReduction = true;
19351
+ }
19352
+ if (isIncomplete(flowType)) {
19353
+ seenIncomplete = true;
19354
+ }
19355
+ }
19356
+ }
19335
19357
return createFlowType(getUnionOrEvolvingArrayType(antecedentTypes, subtypeReduction ? UnionReduction.Subtype : UnionReduction.Literal), seenIncomplete);
19336
19358
}
19337
19359
0 commit comments