@@ -820,6 +820,8 @@ namespace ts {
820
820
let flowLoopCount = 0;
821
821
let sharedFlowCount = 0;
822
822
let flowAnalysisDisabled = false;
823
+ let lastFlowNode: FlowNode | undefined;
824
+ let lastFlowNodeReachable: boolean;
823
825
824
826
const emptyStringType = getLiteralType("");
825
827
const zeroType = getLiteralType(0);
@@ -16995,11 +16997,17 @@ namespace ts {
16995
16997
}
16996
16998
16997
16999
function isReachableFlowNode(flow: FlowNode) {
16998
- return isReachableFlowNodeWorker(flow, /*skipCacheCheck*/ false);
17000
+ const result = isReachableFlowNodeWorker(flow, /*skipCacheCheck*/ false);
17001
+ lastFlowNode = flow;
17002
+ lastFlowNodeReachable = result;
17003
+ return result;
16999
17004
}
17000
17005
17001
17006
function isReachableFlowNodeWorker(flow: FlowNode, noCacheCheck: boolean): boolean {
17002
17007
while (true) {
17008
+ if (flow === lastFlowNode) {
17009
+ return lastFlowNodeReachable;
17010
+ }
17003
17011
const flags = flow.flags;
17004
17012
if (flags & FlowFlags.Shared) {
17005
17013
if (!noCacheCheck) {
@@ -17329,9 +17337,6 @@ namespace ts {
17329
17337
}
17330
17338
17331
17339
function getTypeAtSwitchClause(flow: FlowSwitchClause): FlowType {
17332
- if (flow.clauseStart === flow.clauseEnd && isExhaustiveSwitchStatement(flow.switchStatement)) {
17333
- return neverType;
17334
- }
17335
17340
const expr = flow.switchStatement.expression;
17336
17341
const flowType = getTypeAtFlowNode(flow.antecedent);
17337
17342
let type = getTypeFromFlowType(flowType);
@@ -17350,6 +17355,9 @@ namespace ts {
17350
17355
else if (containsMatchingReferenceDiscriminant(reference, expr)) {
17351
17356
type = declaredType;
17352
17357
}
17358
+ else if (flow.clauseStart === flow.clauseEnd && isExhaustiveSwitchStatement(flow.switchStatement)) {
17359
+ return unreachableNeverType;
17360
+ }
17353
17361
return createFlowType(type, isIncomplete(flowType));
17354
17362
}
17355
17363
0 commit comments