@@ -28037,17 +28037,24 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2803728037 }
2803828038
2803928039 function narrowTypeBySwitchOnTrue(type: Type, switchStatement: SwitchStatement, clauseStart: number, clauseEnd: number): Type {
28040- // Equal start and end denotes implicit fallthrough; undefined marks explicit default clause.
28040+ const clauses = switchStatement.caseBlock.clauses.slice(clauseStart, clauseEnd);
2804128041 const defaultIndex = findIndex(switchStatement.caseBlock.clauses, clause => clause.kind === SyntaxKind.DefaultClause);
2804228042 const hasDefaultClause = clauseStart === clauseEnd || (defaultIndex >= clauseStart && defaultIndex < clauseEnd);
2804328043 if (hasDefaultClause) {
28044- // Here we'd need to find the opposite of all of the other cases, but without control flow,
28045- // the best we can do is to not narrow at all.
28046- return type;
28044+ // In the default case, we need to assume that all of the other cases were false,
28045+ // but also that any of the other cases in this block are true.
28046+ const clausesBefore = switchStatement.caseBlock.clauses.slice(0, clauseStart);
28047+ const before = narrowTypeForClauses(type, clausesBefore, /*assumeTrue*/ false);
28048+ const clausesAfter = switchStatement.caseBlock.clauses.slice(clauseEnd);
28049+ const after = narrowTypeForClauses(type, clausesAfter, /*assumeTrue*/ false);
28050+ return getUnionType([narrowTypeForClauses(type, clauses, /*assumeTrue*/ true), before, after]);
2804728051 }
2804828052 // In the non-default cause we create a union of the type narrowed by each of the listed cases.
28049- const clauses = switchStatement.caseBlock.clauses.slice(clauseStart, clauseEnd);
28050- return getUnionType(map(clauses, clause => clause && clause.kind === SyntaxKind.CaseClause ? narrowType(type, clause.expression, /*assumeTrue*/ true) : neverType));
28053+ return narrowTypeForClauses(type, clauses, /*assumeTrue*/ true);
28054+ }
28055+
28056+ function narrowTypeForClauses(type: Type, clauses: CaseOrDefaultClause[], assumeTrue: boolean) {
28057+ return getUnionType(map(clauses, clause => clause.kind === SyntaxKind.CaseClause ? narrowType(type, clause.expression, assumeTrue) : neverType));
2805128058 }
2805228059
2805328060 function isMatchingConstructorReference(expr: Expression) {
0 commit comments