diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 27ec079f614ab..932a5cbc503b8 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1718,7 +1718,8 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void { preSwitchCaseFlow = currentFlow; bind(node.caseBlock); addAntecedent(postSwitchLabel, currentFlow); - const hasDefault = forEach(node.caseBlock.clauses, c => c.kind === SyntaxKind.DefaultClause); + const hasDefault = forEach(node.caseBlock.clauses, c => c.kind === SyntaxKind.DefaultClause) || + (skipParentheses(node.expression).kind === SyntaxKind.TrueKeyword && node.caseBlock.clauses.some(clause => clause.kind === SyntaxKind.CaseClause && skipParentheses(clause.expression).kind === SyntaxKind.TrueKeyword)); // We mark a switch statement as possibly exhaustive if it has no default clause and if all // case clauses have unreachable end points (e.g. they all return). Note, we no longer need // this property in control flow analysis, it's there only for backwards compatibility. diff --git a/tests/baselines/reference/narrowByClauseExpressionInSwitchTrue11.symbols b/tests/baselines/reference/narrowByClauseExpressionInSwitchTrue11.symbols new file mode 100644 index 0000000000000..18c14db6d22f8 --- /dev/null +++ b/tests/baselines/reference/narrowByClauseExpressionInSwitchTrue11.symbols @@ -0,0 +1,46 @@ +//// [tests/cases/compiler/narrowByClauseExpressionInSwitchTrue11.ts] //// + +=== narrowByClauseExpressionInSwitchTrue11.ts === +function uhoh(input: string) : "A"|"B"|"C" { +>uhoh : Symbol(uhoh, Decl(narrowByClauseExpressionInSwitchTrue11.ts, 0, 0)) +>input : Symbol(input, Decl(narrowByClauseExpressionInSwitchTrue11.ts, 0, 14)) + + switch (true) { + case /a/.test(input): +>/a/.test : Symbol(RegExp.test, Decl(lib.es5.d.ts, --, --)) +>test : Symbol(RegExp.test, Decl(lib.es5.d.ts, --, --)) +>input : Symbol(input, Decl(narrowByClauseExpressionInSwitchTrue11.ts, 0, 14)) + + return "A"; + case /b/.test(input): +>/b/.test : Symbol(RegExp.test, Decl(lib.es5.d.ts, --, --)) +>test : Symbol(RegExp.test, Decl(lib.es5.d.ts, --, --)) +>input : Symbol(input, Decl(narrowByClauseExpressionInSwitchTrue11.ts, 0, 14)) + + return "B"; + case true: + return "C"; + } +} + +function uhoh1(input: string) : "A"|"B"|"C" { +>uhoh1 : Symbol(uhoh1, Decl(narrowByClauseExpressionInSwitchTrue11.ts, 9, 1)) +>input : Symbol(input, Decl(narrowByClauseExpressionInSwitchTrue11.ts, 11, 15)) + + switch ((true)) { + case /a/.test(input): +>/a/.test : Symbol(RegExp.test, Decl(lib.es5.d.ts, --, --)) +>test : Symbol(RegExp.test, Decl(lib.es5.d.ts, --, --)) +>input : Symbol(input, Decl(narrowByClauseExpressionInSwitchTrue11.ts, 11, 15)) + + return "A"; + case /b/.test(input): +>/b/.test : Symbol(RegExp.test, Decl(lib.es5.d.ts, --, --)) +>test : Symbol(RegExp.test, Decl(lib.es5.d.ts, --, --)) +>input : Symbol(input, Decl(narrowByClauseExpressionInSwitchTrue11.ts, 11, 15)) + + return "B"; + case (true): + return "C"; + } +} diff --git a/tests/baselines/reference/narrowByClauseExpressionInSwitchTrue11.types b/tests/baselines/reference/narrowByClauseExpressionInSwitchTrue11.types new file mode 100644 index 0000000000000..555200bfa67e2 --- /dev/null +++ b/tests/baselines/reference/narrowByClauseExpressionInSwitchTrue11.types @@ -0,0 +1,110 @@ +//// [tests/cases/compiler/narrowByClauseExpressionInSwitchTrue11.ts] //// + +=== narrowByClauseExpressionInSwitchTrue11.ts === +function uhoh(input: string) : "A"|"B"|"C" { +>uhoh : (input: string) => "A" | "B" | "C" +> : ^ ^^ ^^^^^ +>input : string +> : ^^^^^^ + + switch (true) { +>true : true +> : ^^^^ + + case /a/.test(input): +>/a/.test(input) : boolean +> : ^^^^^^^ +>/a/.test : (string: string) => boolean +> : ^ ^^ ^^^^^ +>/a/ : RegExp +> : ^^^^^^ +>test : (string: string) => boolean +> : ^ ^^ ^^^^^ +>input : string +> : ^^^^^^ + + return "A"; +>"A" : "A" +> : ^^^ + + case /b/.test(input): +>/b/.test(input) : boolean +> : ^^^^^^^ +>/b/.test : (string: string) => boolean +> : ^ ^^ ^^^^^ +>/b/ : RegExp +> : ^^^^^^ +>test : (string: string) => boolean +> : ^ ^^ ^^^^^ +>input : string +> : ^^^^^^ + + return "B"; +>"B" : "B" +> : ^^^ + + case true: +>true : true +> : ^^^^ + + return "C"; +>"C" : "C" +> : ^^^ + } +} + +function uhoh1(input: string) : "A"|"B"|"C" { +>uhoh1 : (input: string) => "A" | "B" | "C" +> : ^ ^^ ^^^^^ +>input : string +> : ^^^^^^ + + switch ((true)) { +>(true) : true +> : ^^^^ +>true : true +> : ^^^^ + + case /a/.test(input): +>/a/.test(input) : boolean +> : ^^^^^^^ +>/a/.test : (string: string) => boolean +> : ^ ^^ ^^^^^ +>/a/ : RegExp +> : ^^^^^^ +>test : (string: string) => boolean +> : ^ ^^ ^^^^^ +>input : string +> : ^^^^^^ + + return "A"; +>"A" : "A" +> : ^^^ + + case /b/.test(input): +>/b/.test(input) : boolean +> : ^^^^^^^ +>/b/.test : (string: string) => boolean +> : ^ ^^ ^^^^^ +>/b/ : RegExp +> : ^^^^^^ +>test : (string: string) => boolean +> : ^ ^^ ^^^^^ +>input : string +> : ^^^^^^ + + return "B"; +>"B" : "B" +> : ^^^ + + case (true): +>(true) : true +> : ^^^^ +>true : true +> : ^^^^ + + return "C"; +>"C" : "C" +> : ^^^ + } +} diff --git a/tests/cases/compiler/narrowByClauseExpressionInSwitchTrue11.ts b/tests/cases/compiler/narrowByClauseExpressionInSwitchTrue11.ts new file mode 100644 index 0000000000000..ffff0a18372fe --- /dev/null +++ b/tests/cases/compiler/narrowByClauseExpressionInSwitchTrue11.ts @@ -0,0 +1,24 @@ +// @strict: true +// @noEmit: true + +function uhoh(input: string) : "A"|"B"|"C" { + switch (true) { + case /a/.test(input): + return "A"; + case /b/.test(input): + return "B"; + case true: + return "C"; + } +} + +function uhoh1(input: string) : "A"|"B"|"C" { + switch ((true)) { + case /a/.test(input): + return "A"; + case /b/.test(input): + return "B"; + case (true): + return "C"; + } +} \ No newline at end of file