swc/crates/swc_ecma_parser/tests/tsc/exhaustiveSwitchStatements1.ts
2022-02-04 17:08:38 +09:00

253 lines
4.7 KiB
TypeScript

// @strict: true
// @allowUnreachableCode: false
// @declaration: true
function f1(x: 1 | 2): string {
if (!!true) {
switch (x) {
case 1: return 'a';
case 2: return 'b';
}
x; // Unreachable
}
else {
throw 0;
}
}
function f2(x: 1 | 2) {
let z: number;
switch (x) {
case 1: z = 10; break;
case 2: z = 20; break;
}
z; // Definitely assigned
}
function f3(x: 1 | 2) {
switch (x) {
case 1: return 10;
case 2: return 20;
// Default considered reachable to allow defensive coding
default: throw new Error("Bad input");
}
}
// Repro from #11572
enum E { A, B }
function f(e: E): number {
switch (e) {
case E.A: return 0
case E.B: return 1
}
}
function g(e: E): number {
if (!true)
return -1
else
switch (e) {
case E.A: return 0
case E.B: return 1
}
}
// Repro from #12668
interface Square { kind: "square"; size: number; }
interface Rectangle { kind: "rectangle"; width: number; height: number; }
interface Circle { kind: "circle"; radius: number; }
interface Triangle { kind: "triangle"; side: number; }
type Shape = Square | Rectangle | Circle | Triangle;
function area(s: Shape): number {
let area;
switch (s.kind) {
case "square": area = s.size * s.size; break;
case "rectangle": area = s.width * s.height; break;
case "circle": area = Math.PI * s.radius * s.radius; break;
case "triangle": area = Math.sqrt(3) / 4 * s.side * s.side; break;
}
return area;
}
function areaWrapped(s: Shape): number {
let area;
area = (() => {
switch (s.kind) {
case "square": return s.size * s.size;
case "rectangle": return s.width * s.height;
case "circle": return Math.PI * s.radius * s.radius;
case "triangle": return Math.sqrt(3) / 4 * s.side * s.side;
}
})();
return area;
}
// Repro from #13241
enum MyEnum {
A,
B
}
function thisGivesError(e: MyEnum): string {
let s: string;
switch (e) {
case MyEnum.A: s = "it was A"; break;
case MyEnum.B: s = "it was B"; break;
}
return s;
}
function good1(e: MyEnum): string {
let s: string;
switch (e) {
case MyEnum.A: s = "it was A"; break;
case MyEnum.B: s = "it was B"; break;
default: s = "it was something else"; break;
}
return s;
}
function good2(e: MyEnum): string {
switch (e) {
case MyEnum.A: return "it was A";
case MyEnum.B: return "it was B";
}
}
// Repro from #18362
enum Level {
One,
Two,
}
const doSomethingWithLevel = (level: Level) => {
let next: Level;
switch (level) {
case Level.One:
next = Level.Two;
break;
case Level.Two:
next = Level.One;
break;
}
return next;
};
// Repro from #20409
interface Square2 {
kind: "square";
size: number;
}
interface Circle2 {
kind: "circle";
radius: number;
}
type Shape2 = Square2 | Circle2;
function withDefault(s1: Shape2, s2: Shape2): string {
switch (s1.kind) {
case "square":
return "1";
case "circle":
switch (s2.kind) {
case "square":
return "2";
case "circle":
return "3";
default:
return "never";
}
}
}
function withoutDefault(s1: Shape2, s2: Shape2): string {
switch (s1.kind) {
case "square":
return "1";
case "circle":
switch (s2.kind) {
case "square":
return "2";
case "circle":
return "3";
}
}
}
// Repro from #20823
function test4(value: 1 | 2) {
let x: string;
switch (value) {
case 1: x = "one"; break;
case 2: x = "two"; break;
}
return x;
}
// Repro from #34661
enum Animal { DOG, CAT }
declare const zoo: { animal: Animal } | undefined;
function expression(): Animal {
switch (zoo?.animal ?? Animal.DOG) {
case Animal.DOG: return Animal.DOG
case Animal.CAT: return Animal.CAT
}
}
// Repro from #34840
function foo() {
const foo: number | undefined = 0;
while (true) {
const stats = foo;
switch (stats) {
case 1: break;
case 2: break;
}
}
}
// Repro from #35070
type O = {
a: number,
b: number
};
type K = keyof O | 'c';
function ff(o: O, k: K) {
switch(k) {
case 'c':
k = 'a';
}
k === 'c'; // Error
return o[k];
}
// Repro from #35431
type A = { kind: "abc" } | { kind: "def" };
function f35431(a: A) {
switch (a.kind) {
case "abc":
case "def": return;
default:
a!.kind; // Error expected
}
}