Skip to content

Commit 0d4beb0

Browse files
authored
Merge pull request #12538 from Microsoft/fixExhaustiveSwitchCheck
Fix exhaustive switch check
2 parents 5b873fa + 2b07216 commit 0d4beb0

5 files changed

+131
-1
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13850,7 +13850,7 @@ namespace ts {
1385013850
if (!switchTypes.length) {
1385113851
return false;
1385213852
}
13853-
return eachTypeContainedIn(type, switchTypes);
13853+
return eachTypeContainedIn(mapType(type, getRegularTypeOfLiteralType), switchTypes);
1385413854
}
1385513855

1385613856
function functionHasImplicitReturn(func: FunctionLikeDeclaration) {
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//// [exhaustiveSwitchWithWideningLiteralTypes.ts]
2+
3+
// Repro from #12529
4+
5+
class A {
6+
readonly kind = "A"; // (property) A.kind: "A"
7+
}
8+
9+
class B {
10+
readonly kind = "B"; // (property) B.kind: "B"
11+
}
12+
13+
function f(value: A | B): number {
14+
switch(value.kind) {
15+
case "A": return 0;
16+
case "B": return 1;
17+
}
18+
}
19+
20+
//// [exhaustiveSwitchWithWideningLiteralTypes.js]
21+
// Repro from #12529
22+
var A = (function () {
23+
function A() {
24+
this.kind = "A"; // (property) A.kind: "A"
25+
}
26+
return A;
27+
}());
28+
var B = (function () {
29+
function B() {
30+
this.kind = "B"; // (property) B.kind: "B"
31+
}
32+
return B;
33+
}());
34+
function f(value) {
35+
switch (value.kind) {
36+
case "A": return 0;
37+
case "B": return 1;
38+
}
39+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
=== tests/cases/compiler/exhaustiveSwitchWithWideningLiteralTypes.ts ===
2+
3+
// Repro from #12529
4+
5+
class A {
6+
>A : Symbol(A, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 0, 0))
7+
8+
readonly kind = "A"; // (property) A.kind: "A"
9+
>kind : Symbol(A.kind, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 3, 9))
10+
}
11+
12+
class B {
13+
>B : Symbol(B, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 5, 1))
14+
15+
readonly kind = "B"; // (property) B.kind: "B"
16+
>kind : Symbol(B.kind, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 7, 9))
17+
}
18+
19+
function f(value: A | B): number {
20+
>f : Symbol(f, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 9, 1))
21+
>value : Symbol(value, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 11, 11))
22+
>A : Symbol(A, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 0, 0))
23+
>B : Symbol(B, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 5, 1))
24+
25+
switch(value.kind) {
26+
>value.kind : Symbol(kind, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 3, 9), Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 7, 9))
27+
>value : Symbol(value, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 11, 11))
28+
>kind : Symbol(kind, Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 3, 9), Decl(exhaustiveSwitchWithWideningLiteralTypes.ts, 7, 9))
29+
30+
case "A": return 0;
31+
case "B": return 1;
32+
}
33+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
=== tests/cases/compiler/exhaustiveSwitchWithWideningLiteralTypes.ts ===
2+
3+
// Repro from #12529
4+
5+
class A {
6+
>A : A
7+
8+
readonly kind = "A"; // (property) A.kind: "A"
9+
>kind : "A"
10+
>"A" : "A"
11+
}
12+
13+
class B {
14+
>B : B
15+
16+
readonly kind = "B"; // (property) B.kind: "B"
17+
>kind : "B"
18+
>"B" : "B"
19+
}
20+
21+
function f(value: A | B): number {
22+
>f : (value: A | B) => number
23+
>value : A | B
24+
>A : A
25+
>B : B
26+
27+
switch(value.kind) {
28+
>value.kind : "A" | "B"
29+
>value : A | B
30+
>kind : "A" | "B"
31+
32+
case "A": return 0;
33+
>"A" : "A"
34+
>0 : 0
35+
36+
case "B": return 1;
37+
>"B" : "B"
38+
>1 : 1
39+
}
40+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// @strictNullChecks: true
2+
3+
// Repro from #12529
4+
5+
class A {
6+
readonly kind = "A"; // (property) A.kind: "A"
7+
}
8+
9+
class B {
10+
readonly kind = "B"; // (property) B.kind: "B"
11+
}
12+
13+
function f(value: A | B): number {
14+
switch(value.kind) {
15+
case "A": return 0;
16+
case "B": return 1;
17+
}
18+
}

0 commit comments

Comments
 (0)