diff --git a/tests/cases/conformance/controlFlow/controlFlowAssignmentExpression.ts b/tests/cases/conformance/controlFlow/controlFlowAssignmentExpression.ts new file mode 100644 index 0000000000000..83bf75ab94d0c --- /dev/null +++ b/tests/cases/conformance/controlFlow/controlFlowAssignmentExpression.ts @@ -0,0 +1,10 @@ +let x: string | boolean | number; +let obj: any; + +x = ""; +x = x.length; +x; // number + +x = true; +(x = "", obj).foo = (x = x.length); +x; // number diff --git a/tests/cases/conformance/controlFlow/controlFlowBinaryAndExpression.ts b/tests/cases/conformance/controlFlow/controlFlowBinaryAndExpression.ts new file mode 100644 index 0000000000000..caaef9b890f52 --- /dev/null +++ b/tests/cases/conformance/controlFlow/controlFlowBinaryAndExpression.ts @@ -0,0 +1,9 @@ +let x: string | number | boolean; +let cond: boolean; + +(x = "") && (x = 0); +x; // string | number + +x = ""; +cond && (x = 0); +x; // string | number diff --git a/tests/cases/conformance/controlFlow/controlFlowBinaryOrExpression.ts b/tests/cases/conformance/controlFlow/controlFlowBinaryOrExpression.ts new file mode 100644 index 0000000000000..75b24622e0028 --- /dev/null +++ b/tests/cases/conformance/controlFlow/controlFlowBinaryOrExpression.ts @@ -0,0 +1,9 @@ +let x: string | number | boolean; +let cond: boolean; + +(x = "") || (x = 0); +x; // string | number + +x = ""; +cond || (x = 0); +x; // string | number diff --git a/tests/cases/conformance/controlFlow/controlFlowConditionalExpression.ts b/tests/cases/conformance/controlFlow/controlFlowConditionalExpression.ts new file mode 100644 index 0000000000000..c1c1d9956ea05 --- /dev/null +++ b/tests/cases/conformance/controlFlow/controlFlowConditionalExpression.ts @@ -0,0 +1,5 @@ +let x: string | number | boolean; +let cond: boolean; + +cond ? x = "" : x = 3; +x; // string | number diff --git a/tests/cases/conformance/controlFlow/controlFlowDoWhileStatement.ts b/tests/cases/conformance/controlFlow/controlFlowDoWhileStatement.ts new file mode 100644 index 0000000000000..bd253bc064def --- /dev/null +++ b/tests/cases/conformance/controlFlow/controlFlowDoWhileStatement.ts @@ -0,0 +1,76 @@ +let cond: boolean; +function a() { + let x: string | number; + x = ""; + do { + x; // string + } while (cond) +} +function b() { + let x: string | number; + x = ""; + do { + x; // string + x = 42; + break; + } while (cond) +} +function c() { + let x: string | number; + x = ""; + do { + x; // string + x = undefined; + if (typeof x === "string") continue; + break; + } while (cond) +} +function d() { + let x: string | number; + x = 1000; + do { + x; // number + x = ""; + } while (x = x.length) + x; // number +} +function e() { + let x: string | number; + x = ""; + do { + x = 42; + } while (cond) + x; // number +} +function f() { + let x: string | number | boolean | RegExp | Function; + x = ""; + do { + if (cond) { + x = 42; + break; + } + if (cond) { + x = true; + continue; + } + x = /a/; + } while (cond) + x; // number | boolean | RegExp +} +function g() { + let x: string | number | boolean | RegExp | Function; + x = ""; + do { + if (cond) { + x = 42; + break; + } + if (cond) { + x = true; + continue; + } + x = /a/; + } while (true) + x; // number +} diff --git a/tests/cases/conformance/controlFlow/controlFlowForInStatement.ts b/tests/cases/conformance/controlFlow/controlFlowForInStatement.ts new file mode 100644 index 0000000000000..a22e79506c250 --- /dev/null +++ b/tests/cases/conformance/controlFlow/controlFlowForInStatement.ts @@ -0,0 +1,17 @@ +let x: string | number | boolean | RegExp | Function; +let obj: any; +let cond: boolean; + +x = /a/; +for (let y in obj) { + x = y; + if (cond) { + x = 42; + continue; + } + if (cond) { + x = true; + break; + } +} +x; // RegExp | string | number | boolean diff --git a/tests/cases/conformance/controlFlow/controlFlowForOfStatement.ts b/tests/cases/conformance/controlFlow/controlFlowForOfStatement.ts new file mode 100644 index 0000000000000..ac4c584e1dcae --- /dev/null +++ b/tests/cases/conformance/controlFlow/controlFlowForOfStatement.ts @@ -0,0 +1,10 @@ +let obj: number[]; +let x: string | number | boolean | RegExp; + +function a() { + x = true; + for (x of obj) { + x = x.toExponential(); + } + x; // number | boolean +} diff --git a/tests/cases/conformance/controlFlow/controlFlowForStatement.ts b/tests/cases/conformance/controlFlow/controlFlowForStatement.ts new file mode 100644 index 0000000000000..d9e46781aa7b5 --- /dev/null +++ b/tests/cases/conformance/controlFlow/controlFlowForStatement.ts @@ -0,0 +1,41 @@ +let cond: boolean; +function a() { + let x: string | number | boolean; + for (x = ""; cond; x = 5) { + x; // string | number + } +} +function b() { + let x: string | number | boolean; + for (x = 5; cond; x = x.length) { + x; // number + x = ""; + } +} +function c() { + let x: string | number | boolean; + for (x = 5; x = x.toExponential(); x = 5) { + x; // string + } +} +function d() { + let x: string | number | boolean; + for (x = ""; typeof x === "string"; x = 5) { + x; // string + } +} +function e() { + let x: string | number | boolean | RegExp; + for (x = "" || 0; typeof x !== "string"; x = "" || true) { + x; // number | boolean + } +} +function f() { + let x: string | number | boolean; + for (; typeof x !== "string";) { + x; // number | boolean + if (typeof x === "number") break; + x = undefined; + } + x; // string | number +} diff --git a/tests/cases/conformance/controlFlow/controlFlowIfStatement.ts b/tests/cases/conformance/controlFlow/controlFlowIfStatement.ts new file mode 100644 index 0000000000000..c9e9be92f8e7e --- /dev/null +++ b/tests/cases/conformance/controlFlow/controlFlowIfStatement.ts @@ -0,0 +1,36 @@ +let x: string | number | boolean | RegExp; +let cond: boolean; + +x = /a/; +if (x /* RegExp */, (x = true)) { + x; // boolean + x = ""; +} +else { + x; // boolean + x = 42; +} +x; // string | number + +function a() { + let x: string | number; + if (cond) { + x = 42; + } + else { + x = ""; + return; + } + x; // number +} +function b() { + let x: string | number; + if (cond) { + x = 42; + throw ""; + } + else { + x = ""; + } + x; // string +} diff --git a/tests/cases/conformance/controlFlow/controlFlowWhileStatement.ts b/tests/cases/conformance/controlFlow/controlFlowWhileStatement.ts new file mode 100644 index 0000000000000..697a867b88689 --- /dev/null +++ b/tests/cases/conformance/controlFlow/controlFlowWhileStatement.ts @@ -0,0 +1,75 @@ +let cond: boolean; +function a() { + let x: string | number; + x = ""; + while (cond) { + x; // string + } +} +function b() { + let x: string | number; + x = ""; + while (cond) { + x; // string + x = 42; + break; + } +} +function c() { + let x: string | number; + x = ""; + while (cond) { + x; // string + x = undefined; + if (typeof x === "string") continue; + break; + } +} +function d() { + let x: string | number; + x = ""; + while (x = x.length) { + x; // number + x = ""; + } +} +function e() { + let x: string | number; + x = ""; + while (cond) { + x = 42; + } + x; // string | number +} +function f() { + let x: string | number | boolean | RegExp | Function; + x = ""; + while (cond) { + if (cond) { + x = 42; + break; + } + if (cond) { + x = true; + continue; + } + x = /a/; + } + x; // string | number | boolean | RegExp +} +function g() { + let x: string | number | boolean | RegExp | Function; + x = ""; + while (true) { + if (cond) { + x = 42; + break; + } + if (cond) { + x = true; + continue; + } + x = /a/; + } + x; // number +} diff --git a/tests/cases/conformance/expressions/assignmentOperator/assignmentTypeNarrowing.ts b/tests/cases/conformance/expressions/assignmentOperator/assignmentTypeNarrowing.ts new file mode 100644 index 0000000000000..0e5e257635a57 --- /dev/null +++ b/tests/cases/conformance/expressions/assignmentOperator/assignmentTypeNarrowing.ts @@ -0,0 +1,28 @@ +let x: string | number | boolean | RegExp; + +x = ""; +x; // string + +[x] = [true]; +x; // boolean + +[x = ""] = [1]; +x; // string | number + +({x} = {x: true}); +x; // boolean + +({y: x} = {y: 1}); +x; // number + +({x = ""} = {x: true}); +x; // string | boolean + +({y: x = /a/} = {y: 1}); +x; // number | RegExp + +let a: string[]; + +for (x of a) { + x; // string +} diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardsInDoStatement.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardsInDoStatement.ts new file mode 100644 index 0000000000000..1afbe515df8d4 --- /dev/null +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardsInDoStatement.ts @@ -0,0 +1,27 @@ +let cond: boolean; +function a(x: string | number | boolean) { + x = true; + do { + x; // boolean | string + x = undefined; + } while (typeof x === "string") + x; // number | boolean +} +function b(x: string | number | boolean) { + x = true; + do { + x; // boolean | string + if (cond) continue; + x = undefined; + } while (typeof x === "string") + x; // number | boolean +} +function c(x: string | number) { + x = ""; + do { + x; // string + if (cond) break; + x = undefined; + } while (typeof x === "string") + x; // string | number +} diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardsInForStatement.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardsInForStatement.ts new file mode 100644 index 0000000000000..cf5c008e80050 --- /dev/null +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardsInForStatement.ts @@ -0,0 +1,21 @@ +let cond: boolean; +function a(x: string | number) { + for (x = undefined; typeof x !== "number"; x = undefined) { + x; // string + } + x; // number +} +function b(x: string | number) { + for (x = undefined; typeof x !== "number"; x = undefined) { + x; // string + if (cond) continue; + } + x; // number +} +function c(x: string | number) { + for (x = undefined; typeof x !== "number"; x = undefined) { + x; // string + if (cond) break; + } + x; // string | number +} diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardsInWhileStatement.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardsInWhileStatement.ts new file mode 100644 index 0000000000000..642c899579531 --- /dev/null +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardsInWhileStatement.ts @@ -0,0 +1,24 @@ +let cond: boolean; +function a(x: string | number) { + while (typeof x === "string") { + x; // string + x = undefined; + } + x; // number +} +function b(x: string | number) { + while (typeof x === "string") { + if (cond) continue; + x; // string + x = undefined; + } + x; // number +} +function c(x: string | number) { + while (typeof x === "string") { + if (cond) break; + x; // string + x = undefined; + } + x; // string | number +}