diff --git a/internal/checker/flow.go b/internal/checker/flow.go index 84c0d81e8f..352d396d67 100644 --- a/internal/checker/flow.go +++ b/internal/checker/flow.go @@ -1970,15 +1970,11 @@ func (c *Checker) getSwitchClauseTypeOfWitnesses(node *ast.Node) []string { witnesses := make([]string, len(clauses)) for i, clause := range clauses { if clause.Kind == ast.KindCaseClause { - var text string - if ast.IsStringLiteralLike(clause.Expression()) { - text = clause.Expression().Text() - } - if text == "" { + if !ast.IsStringLiteralLike(clause.Expression()) { witnesses = nil break } - if !slices.Contains(witnesses, text) { + if text := clause.Expression().Text(); !slices.Contains(witnesses, text) { witnesses[i] = text } } diff --git a/testdata/baselines/reference/compiler/typeofSwitchEmptyStringCase.errors.txt b/testdata/baselines/reference/compiler/typeofSwitchEmptyStringCase.errors.txt new file mode 100644 index 0000000000..a160a2075c --- /dev/null +++ b/testdata/baselines/reference/compiler/typeofSwitchEmptyStringCase.errors.txt @@ -0,0 +1,17 @@ +typeofSwitchEmptyStringCase.ts(5,10): error TS2678: Type '""' is not comparable to type '"bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined"'. + + +==== typeofSwitchEmptyStringCase.ts (1 errors) ==== + // https://github.com/microsoft/typescript-go/issues/3909 + + function f(x: string | number) { + switch (typeof x) { + case "": + ~~ +!!! error TS2678: Type '""' is not comparable to type '"bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined"'. + case "string": + x.charAt(0); + break; + } + } + \ No newline at end of file diff --git a/testdata/baselines/reference/compiler/typeofSwitchEmptyStringCase.symbols b/testdata/baselines/reference/compiler/typeofSwitchEmptyStringCase.symbols new file mode 100644 index 0000000000..b8f0a9ec17 --- /dev/null +++ b/testdata/baselines/reference/compiler/typeofSwitchEmptyStringCase.symbols @@ -0,0 +1,23 @@ +//// [tests/cases/compiler/typeofSwitchEmptyStringCase.ts] //// + +=== typeofSwitchEmptyStringCase.ts === +// https://github.com/microsoft/typescript-go/issues/3909 + +function f(x: string | number) { +>f : Symbol(f, Decl(typeofSwitchEmptyStringCase.ts, 0, 0)) +>x : Symbol(x, Decl(typeofSwitchEmptyStringCase.ts, 2, 11)) + + switch (typeof x) { +>x : Symbol(x, Decl(typeofSwitchEmptyStringCase.ts, 2, 11)) + + case "": + case "string": + x.charAt(0); +>x.charAt : Symbol(String.charAt, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(typeofSwitchEmptyStringCase.ts, 2, 11)) +>charAt : Symbol(String.charAt, Decl(lib.es5.d.ts, --, --)) + + break; + } +} + diff --git a/testdata/baselines/reference/compiler/typeofSwitchEmptyStringCase.types b/testdata/baselines/reference/compiler/typeofSwitchEmptyStringCase.types new file mode 100644 index 0000000000..bf16eba7f8 --- /dev/null +++ b/testdata/baselines/reference/compiler/typeofSwitchEmptyStringCase.types @@ -0,0 +1,30 @@ +//// [tests/cases/compiler/typeofSwitchEmptyStringCase.ts] //// + +=== typeofSwitchEmptyStringCase.ts === +// https://github.com/microsoft/typescript-go/issues/3909 + +function f(x: string | number) { +>f : (x: string | number) => void +>x : string | number + + switch (typeof x) { +>typeof x : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined" +>x : string | number + + case "": +>"" : "" + + case "string": +>"string" : "string" + + x.charAt(0); +>x.charAt(0) : string +>x.charAt : (pos: number) => string +>x : string +>charAt : (pos: number) => string +>0 : 0 + + break; + } +} + diff --git a/testdata/tests/cases/compiler/typeofSwitchEmptyStringCase.ts b/testdata/tests/cases/compiler/typeofSwitchEmptyStringCase.ts new file mode 100644 index 0000000000..5c86c47ce4 --- /dev/null +++ b/testdata/tests/cases/compiler/typeofSwitchEmptyStringCase.ts @@ -0,0 +1,12 @@ +// @noEmit: true + +// https://github.com/microsoft/typescript-go/issues/3909 + +function f(x: string | number) { + switch (typeof x) { + case "": + case "string": + x.charAt(0); + break; + } +}