Skip to content

Commit a98c233

Browse files
committed
Attempt to fix things
1 parent 334a80f commit a98c233

2 files changed

Lines changed: 14 additions & 7 deletions

File tree

src/compiler/checker.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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) {

tests/baselines/reference/narrowByClauseExpressionInSwitchTrue4.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ switch (true) {
1414

1515
default:
1616
f;
17-
>f : "a" | "b" | "c"
17+
>f : "a" | "c"
1818

1919
case f === "b":
2020
>f === "b" : boolean

0 commit comments

Comments
 (0)