2014-11-05 23:21:32 +01:00
|
|
|
//// [typeGuardsInFunctionAndModuleBlock.ts]
|
|
|
|
// typeguards are scoped in function/module block
|
|
|
|
|
|
|
|
function foo(x: number | string | boolean) {
|
|
|
|
return typeof x === "string"
|
|
|
|
? x
|
|
|
|
: function f() {
|
2014-11-14 19:42:31 +01:00
|
|
|
var b = x; // number | boolean
|
2014-11-05 23:21:32 +01:00
|
|
|
return typeof x === "boolean"
|
|
|
|
? x.toString() // boolean
|
2014-11-14 19:42:31 +01:00
|
|
|
: x.toString(); // number
|
2014-11-05 23:21:32 +01:00
|
|
|
} ();
|
|
|
|
}
|
|
|
|
function foo2(x: number | string | boolean) {
|
|
|
|
return typeof x === "string"
|
|
|
|
? x
|
|
|
|
: function f(a: number | boolean) {
|
2014-11-14 19:42:31 +01:00
|
|
|
var b = x; // new scope - number | boolean
|
2014-11-05 23:21:32 +01:00
|
|
|
return typeof x === "boolean"
|
|
|
|
? x.toString() // boolean
|
2014-11-14 19:42:31 +01:00
|
|
|
: x.toString(); // number
|
2014-11-05 23:21:32 +01:00
|
|
|
} (x); // x here is narrowed to number | boolean
|
|
|
|
}
|
|
|
|
function foo3(x: number | string | boolean) {
|
|
|
|
return typeof x === "string"
|
|
|
|
? x
|
|
|
|
: (() => {
|
2014-11-14 19:42:31 +01:00
|
|
|
var b = x; // new scope - number | boolean
|
2014-11-05 23:21:32 +01:00
|
|
|
return typeof x === "boolean"
|
|
|
|
? x.toString() // boolean
|
2014-11-14 19:42:31 +01:00
|
|
|
: x.toString(); // number
|
2014-11-05 23:21:32 +01:00
|
|
|
})();
|
|
|
|
}
|
|
|
|
function foo4(x: number | string | boolean) {
|
|
|
|
return typeof x === "string"
|
|
|
|
? x
|
|
|
|
: ((a: number | boolean) => {
|
2014-11-14 19:42:31 +01:00
|
|
|
var b = x; // new scope - number | boolean
|
2014-11-05 23:21:32 +01:00
|
|
|
return typeof x === "boolean"
|
|
|
|
? x.toString() // boolean
|
2014-11-14 19:42:31 +01:00
|
|
|
: x.toString(); // number
|
2014-11-05 23:21:32 +01:00
|
|
|
})(x); // x here is narrowed to number | boolean
|
|
|
|
}
|
2014-11-14 22:36:09 +01:00
|
|
|
// Type guards affect nested function expressions, but not nested function declarations
|
|
|
|
function foo5(x: number | string | boolean) {
|
|
|
|
if (typeof x === "string") {
|
|
|
|
var y = x; // string;
|
|
|
|
function foo() {
|
|
|
|
var z = x; // number | string | boolean, type guard has no effect
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-11-05 23:21:32 +01:00
|
|
|
module m {
|
|
|
|
var x: number | string | boolean;
|
|
|
|
module m2 {
|
|
|
|
var b = x; // new scope - number | boolean | string
|
|
|
|
var y: string;
|
|
|
|
if (typeof x === "string") {
|
|
|
|
y = x // string;
|
|
|
|
} else {
|
|
|
|
y = typeof x === "boolean"
|
|
|
|
? x.toString() // boolean
|
|
|
|
: x.toString(); // number
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
module m1 {
|
|
|
|
var x: number | string | boolean;
|
|
|
|
module m2.m3 {
|
|
|
|
var b = x; // new scope - number | boolean | string
|
|
|
|
var y: string;
|
|
|
|
if (typeof x === "string") {
|
|
|
|
y = x // string;
|
|
|
|
} else {
|
|
|
|
y = typeof x === "boolean"
|
|
|
|
? x.toString() // boolean
|
|
|
|
: x.toString(); // number
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//// [typeGuardsInFunctionAndModuleBlock.js]
|
|
|
|
// typeguards are scoped in function/module block
|
|
|
|
function foo(x) {
|
2015-03-26 21:46:35 +01:00
|
|
|
return typeof x === "string"
|
|
|
|
? x
|
|
|
|
: function f() {
|
|
|
|
var b = x; // number | boolean
|
|
|
|
return typeof x === "boolean"
|
|
|
|
? x.toString() // boolean
|
|
|
|
: x.toString(); // number
|
|
|
|
}();
|
2014-11-05 23:21:32 +01:00
|
|
|
}
|
|
|
|
function foo2(x) {
|
2015-03-26 21:46:35 +01:00
|
|
|
return typeof x === "string"
|
|
|
|
? x
|
|
|
|
: function f(a) {
|
|
|
|
var b = x; // new scope - number | boolean
|
|
|
|
return typeof x === "boolean"
|
|
|
|
? x.toString() // boolean
|
|
|
|
: x.toString(); // number
|
|
|
|
}(x); // x here is narrowed to number | boolean
|
2014-11-05 23:21:32 +01:00
|
|
|
}
|
|
|
|
function foo3(x) {
|
2015-03-26 21:46:35 +01:00
|
|
|
return typeof x === "string"
|
|
|
|
? x
|
|
|
|
: (function () {
|
|
|
|
var b = x; // new scope - number | boolean
|
|
|
|
return typeof x === "boolean"
|
|
|
|
? x.toString() // boolean
|
|
|
|
: x.toString(); // number
|
|
|
|
})();
|
2014-11-05 23:21:32 +01:00
|
|
|
}
|
|
|
|
function foo4(x) {
|
2015-03-26 21:46:35 +01:00
|
|
|
return typeof x === "string"
|
|
|
|
? x
|
|
|
|
: (function (a) {
|
|
|
|
var b = x; // new scope - number | boolean
|
|
|
|
return typeof x === "boolean"
|
|
|
|
? x.toString() // boolean
|
|
|
|
: x.toString(); // number
|
|
|
|
})(x); // x here is narrowed to number | boolean
|
2014-11-05 23:21:32 +01:00
|
|
|
}
|
2014-11-14 22:36:09 +01:00
|
|
|
// Type guards affect nested function expressions, but not nested function declarations
|
|
|
|
function foo5(x) {
|
|
|
|
if (typeof x === "string") {
|
|
|
|
var y = x; // string;
|
|
|
|
function foo() {
|
|
|
|
var z = x; // number | string | boolean, type guard has no effect
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-11-05 23:21:32 +01:00
|
|
|
var m;
|
|
|
|
(function (m) {
|
|
|
|
var x;
|
|
|
|
var m2;
|
|
|
|
(function (m2) {
|
|
|
|
var b = x; // new scope - number | boolean | string
|
|
|
|
var y;
|
|
|
|
if (typeof x === "string") {
|
|
|
|
y = x; // string;
|
|
|
|
}
|
|
|
|
else {
|
2015-03-26 21:46:35 +01:00
|
|
|
y = typeof x === "boolean"
|
|
|
|
? x.toString() // boolean
|
|
|
|
: x.toString(); // number
|
2014-11-05 23:21:32 +01:00
|
|
|
}
|
|
|
|
})(m2 || (m2 = {}));
|
|
|
|
})(m || (m = {}));
|
|
|
|
var m1;
|
|
|
|
(function (m1) {
|
|
|
|
var x;
|
|
|
|
var m2;
|
|
|
|
(function (m2) {
|
|
|
|
var m3;
|
|
|
|
(function (m3) {
|
|
|
|
var b = x; // new scope - number | boolean | string
|
|
|
|
var y;
|
|
|
|
if (typeof x === "string") {
|
|
|
|
y = x; // string;
|
|
|
|
}
|
|
|
|
else {
|
2015-03-26 21:46:35 +01:00
|
|
|
y = typeof x === "boolean"
|
|
|
|
? x.toString() // boolean
|
|
|
|
: x.toString(); // number
|
2014-11-05 23:21:32 +01:00
|
|
|
}
|
|
|
|
})(m3 = m2.m3 || (m2.m3 = {}));
|
|
|
|
})(m2 || (m2 = {}));
|
|
|
|
})(m1 || (m1 = {}));
|