From 91b97009f0f69d290cf7d62122399b9ab03004b1 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 14 Nov 2014 10:42:31 -0800 Subject: [PATCH] Modifying tests and accepting new baselines --- .../reference/typeGuardOfFormTypeOfBoolean.js | 58 +++++++----- .../typeGuardOfFormTypeOfBoolean.types | 56 +++++------ .../reference/typeGuardOfFormTypeOfNumber.js | 57 +++++++----- .../typeGuardOfFormTypeOfNumber.types | 63 +++++++------ .../reference/typeGuardOfFormTypeOfOther.js | 57 +++++++----- .../typeGuardOfFormTypeOfOther.types | 55 +++++------ .../reference/typeGuardOfFormTypeOfString.js | 57 +++++++----- .../typeGuardOfFormTypeOfString.types | 63 +++++++------ tests/baselines/reference/typeGuardsDefeat.js | 35 +++---- .../reference/typeGuardsDefeat.types | 52 ++++++----- .../typeGuardsInFunctionAndModuleBlock.js | 32 +++---- .../typeGuardsInFunctionAndModuleBlock.types | 92 +++++++++---------- .../typeGuardOfFormTypeOfBoolean.ts | 31 ++++--- .../typeGuards/typeGuardOfFormTypeOfNumber.ts | 30 +++--- .../typeGuards/typeGuardOfFormTypeOfOther.ts | 30 +++--- .../typeGuards/typeGuardOfFormTypeOfString.ts | 30 +++--- .../typeGuards/typeGuardsDefeat.ts | 18 ++-- .../typeGuardsInFunctionAndModuleBlock.ts | 16 ++-- 18 files changed, 448 insertions(+), 384 deletions(-) diff --git a/tests/baselines/reference/typeGuardOfFormTypeOfBoolean.js b/tests/baselines/reference/typeGuardOfFormTypeOfBoolean.js index 4b675ffd65..3b0ead5b3c 100644 --- a/tests/baselines/reference/typeGuardOfFormTypeOfBoolean.js +++ b/tests/baselines/reference/typeGuardOfFormTypeOfBoolean.js @@ -17,12 +17,6 @@ var c: C; // where s is a string literal with the value 'string', 'number', or 'boolean', // - when true, narrows the type of x to the given primitive type, or // - when false, removes the primitive type from the type of x. -if (typeof strOrNum === "boolean") { - bool = strOrNum; // boolean -} -else { - var z: string | number = strOrNum; // string | number -} if (typeof strOrBool === "boolean") { bool = strOrBool; // boolean } @@ -48,15 +42,18 @@ else { c = boolOrC; // C } +// Narrowing occurs only if target type is a subtype of variable type +if (typeof strOrNum === "boolean") { + var z1: string | number = strOrNum; // string | number +} +else { + var z2: string | number = strOrNum; // string | number +} + + // A type guard of the form typeof x !== s, where s is a string literal, // - when true, narrows the type of x by typeof x === s when false, or // - when false, narrows the type of x by typeof x === s when true. -if (typeof strOrNum !== "boolean") { - var z: string | number = strOrNum; // string | number -} -else { - bool = strOrNum; // boolean -} if (typeof strOrBool !== "boolean") { str = strOrBool; // string } @@ -80,7 +77,16 @@ if (typeof boolOrC !== "boolean") { } else { bool = boolOrC; // boolean -} +} + +// Narrowing occurs only if target type is a subtype of variable type +if (typeof strOrNum !== "boolean") { + var z1: string | number = strOrNum; // string | number +} +else { + var z2: string | number = strOrNum; // string | number +} + //// [typeGuardOfFormTypeOfBoolean.js] var C = (function () { @@ -104,12 +110,6 @@ var c; // where s is a string literal with the value 'string', 'number', or 'boolean', // - when true, narrows the type of x to the given primitive type, or // - when false, removes the primitive type from the type of x. -if (typeof strOrNum === "boolean") { - bool = strOrNum; // boolean -} -else { - var z = strOrNum; // string | number -} if (typeof strOrBool === "boolean") { bool = strOrBool; // boolean } @@ -134,15 +134,16 @@ if (typeof boolOrC === "boolean") { else { c = boolOrC; // C } +// Narrowing occurs only if target type is a subtype of variable type +if (typeof strOrNum === "boolean") { + var z1 = strOrNum; // string | number +} +else { + var z2 = strOrNum; // string | number +} // A type guard of the form typeof x !== s, where s is a string literal, // - when true, narrows the type of x by typeof x === s when false, or // - when false, narrows the type of x by typeof x === s when true. -if (typeof strOrNum !== "boolean") { - var z = strOrNum; // string | number -} -else { - bool = strOrNum; // boolean -} if (typeof strOrBool !== "boolean") { str = strOrBool; // string } @@ -167,3 +168,10 @@ if (typeof boolOrC !== "boolean") { else { bool = boolOrC; // boolean } +// Narrowing occurs only if target type is a subtype of variable type +if (typeof strOrNum !== "boolean") { + var z1 = strOrNum; // string | number +} +else { + var z2 = strOrNum; // string | number +} diff --git a/tests/baselines/reference/typeGuardOfFormTypeOfBoolean.types b/tests/baselines/reference/typeGuardOfFormTypeOfBoolean.types index 6dc9792768..6bbf5c87c4 100644 --- a/tests/baselines/reference/typeGuardOfFormTypeOfBoolean.types +++ b/tests/baselines/reference/typeGuardOfFormTypeOfBoolean.types @@ -44,21 +44,6 @@ var c: C; // where s is a string literal with the value 'string', 'number', or 'boolean', // - when true, narrows the type of x to the given primitive type, or // - when false, removes the primitive type from the type of x. -if (typeof strOrNum === "boolean") { ->typeof strOrNum === "boolean" : boolean ->typeof strOrNum : string ->strOrNum : string | number - - bool = strOrNum; // boolean ->bool = strOrNum : boolean ->bool : boolean ->strOrNum : boolean -} -else { - var z: string | number = strOrNum; // string | number ->z : string | number ->strOrNum : string | number -} if (typeof strOrBool === "boolean") { >typeof strOrBool === "boolean" : boolean >typeof strOrBool : string @@ -124,24 +109,26 @@ else { >boolOrC : C } -// A type guard of the form typeof x !== s, where s is a string literal, -// - when true, narrows the type of x by typeof x === s when false, or -// - when false, narrows the type of x by typeof x === s when true. -if (typeof strOrNum !== "boolean") { ->typeof strOrNum !== "boolean" : boolean +// Narrowing occurs only if target type is a subtype of variable type +if (typeof strOrNum === "boolean") { +>typeof strOrNum === "boolean" : boolean >typeof strOrNum : string >strOrNum : string | number - var z: string | number = strOrNum; // string | number ->z : string | number + var z1: string | number = strOrNum; // string | number +>z1 : string | number >strOrNum : string | number } else { - bool = strOrNum; // boolean ->bool = strOrNum : boolean ->bool : boolean ->strOrNum : boolean + var z2: string | number = strOrNum; // string | number +>z2 : string | number +>strOrNum : string | number } + + +// A type guard of the form typeof x !== s, where s is a string literal, +// - when true, narrows the type of x by typeof x === s when false, or +// - when false, narrows the type of x by typeof x === s when true. if (typeof strOrBool !== "boolean") { >typeof strOrBool !== "boolean" : boolean >typeof strOrBool : string @@ -206,3 +193,20 @@ else { >bool : boolean >boolOrC : boolean } + +// Narrowing occurs only if target type is a subtype of variable type +if (typeof strOrNum !== "boolean") { +>typeof strOrNum !== "boolean" : boolean +>typeof strOrNum : string +>strOrNum : string | number + + var z1: string | number = strOrNum; // string | number +>z1 : string | number +>strOrNum : string | number +} +else { + var z2: string | number = strOrNum; // string | number +>z2 : string | number +>strOrNum : string | number +} + diff --git a/tests/baselines/reference/typeGuardOfFormTypeOfNumber.js b/tests/baselines/reference/typeGuardOfFormTypeOfNumber.js index ff3a43430b..b65ccbb882 100644 --- a/tests/baselines/reference/typeGuardOfFormTypeOfNumber.js +++ b/tests/baselines/reference/typeGuardOfFormTypeOfNumber.js @@ -23,12 +23,6 @@ if (typeof strOrNum === "number") { else { str === strOrNum; // string } -if (typeof strOrBool === "number") { - num = strOrBool; // number -} -else { - var y: string | boolean = strOrBool; // string | boolean -} if (typeof numOrBool === "number") { num = numOrBool; // number } @@ -48,6 +42,14 @@ else { c = numOrC; // C } +// Narrowing occurs only if target type is a subtype of variable type +if (typeof strOrBool === "number") { + var y1: string | boolean = strOrBool; // string | boolean +} +else { + var y2: string | boolean = strOrBool; // string | boolean +} + // A type guard of the form typeof x !== s, where s is a string literal, // - when true, narrows the type of x by typeof x === s when false, or // - when false, narrows the type of x by typeof x === s when true. @@ -57,12 +59,6 @@ if (typeof strOrNum !== "number") { else { num = strOrNum; // number } -if (typeof strOrBool !== "number") { - var y: string | boolean = strOrBool; // string | boolean -} -else { - num = strOrBool; // number -} if (typeof numOrBool !== "number") { var x: number | boolean = numOrBool; // number | boolean } @@ -80,7 +76,16 @@ if (typeof numOrC !== "number") { } else { num = numOrC; // number -} +} + +// Narrowing occurs only if target type is a subtype of variable type +if (typeof strOrBool !== "number") { + var y1: string | boolean = strOrBool; // string | boolean +} +else { + var y2: string | boolean = strOrBool; // string | boolean +} + //// [typeGuardOfFormTypeOfNumber.js] var C = (function () { @@ -110,12 +115,6 @@ if (typeof strOrNum === "number") { else { str === strOrNum; // string } -if (typeof strOrBool === "number") { - num = strOrBool; // number -} -else { - var y = strOrBool; // string | boolean -} if (typeof numOrBool === "number") { num = numOrBool; // number } @@ -134,6 +133,13 @@ if (typeof numOrC === "number") { else { c = numOrC; // C } +// Narrowing occurs only if target type is a subtype of variable type +if (typeof strOrBool === "number") { + var y1 = strOrBool; // string | boolean +} +else { + var y2 = strOrBool; // string | boolean +} // A type guard of the form typeof x !== s, where s is a string literal, // - when true, narrows the type of x by typeof x === s when false, or // - when false, narrows the type of x by typeof x === s when true. @@ -143,12 +149,6 @@ if (typeof strOrNum !== "number") { else { num = strOrNum; // number } -if (typeof strOrBool !== "number") { - var y = strOrBool; // string | boolean -} -else { - num = strOrBool; // number -} if (typeof numOrBool !== "number") { var x = numOrBool; // number | boolean } @@ -167,3 +167,10 @@ if (typeof numOrC !== "number") { else { num = numOrC; // number } +// Narrowing occurs only if target type is a subtype of variable type +if (typeof strOrBool !== "number") { + var y1 = strOrBool; // string | boolean +} +else { + var y2 = strOrBool; // string | boolean +} diff --git a/tests/baselines/reference/typeGuardOfFormTypeOfNumber.types b/tests/baselines/reference/typeGuardOfFormTypeOfNumber.types index 7fd8855ec9..1949f5aa17 100644 --- a/tests/baselines/reference/typeGuardOfFormTypeOfNumber.types +++ b/tests/baselines/reference/typeGuardOfFormTypeOfNumber.types @@ -60,21 +60,6 @@ else { >str : string >strOrNum : string } -if (typeof strOrBool === "number") { ->typeof strOrBool === "number" : boolean ->typeof strOrBool : string ->strOrBool : string | boolean - - num = strOrBool; // number ->num = strOrBool : number ->num : number ->strOrBool : number -} -else { - var y: string | boolean = strOrBool; // string | boolean ->y : string | boolean ->strOrBool : string | boolean -} if (typeof numOrBool === "number") { >typeof numOrBool === "number" : boolean >typeof numOrBool : string @@ -123,6 +108,22 @@ else { >numOrC : C } +// Narrowing occurs only if target type is a subtype of variable type +if (typeof strOrBool === "number") { +>typeof strOrBool === "number" : boolean +>typeof strOrBool : string +>strOrBool : string | boolean + + var y1: string | boolean = strOrBool; // string | boolean +>y1 : string | boolean +>strOrBool : string | boolean +} +else { + var y2: string | boolean = strOrBool; // string | boolean +>y2 : string | boolean +>strOrBool : string | boolean +} + // A type guard of the form typeof x !== s, where s is a string literal, // - when true, narrows the type of x by typeof x === s when false, or // - when false, narrows the type of x by typeof x === s when true. @@ -142,21 +143,6 @@ else { >num : number >strOrNum : number } -if (typeof strOrBool !== "number") { ->typeof strOrBool !== "number" : boolean ->typeof strOrBool : string ->strOrBool : string | boolean - - var y: string | boolean = strOrBool; // string | boolean ->y : string | boolean ->strOrBool : string | boolean -} -else { - num = strOrBool; // number ->num = strOrBool : number ->num : number ->strOrBool : number -} if (typeof numOrBool !== "number") { >typeof numOrBool !== "number" : boolean >typeof numOrBool : string @@ -204,3 +190,20 @@ else { >num : number >numOrC : number } + +// Narrowing occurs only if target type is a subtype of variable type +if (typeof strOrBool !== "number") { +>typeof strOrBool !== "number" : boolean +>typeof strOrBool : string +>strOrBool : string | boolean + + var y1: string | boolean = strOrBool; // string | boolean +>y1 : string | boolean +>strOrBool : string | boolean +} +else { + var y2: string | boolean = strOrBool; // string | boolean +>y2 : string | boolean +>strOrBool : string | boolean +} + diff --git a/tests/baselines/reference/typeGuardOfFormTypeOfOther.js b/tests/baselines/reference/typeGuardOfFormTypeOfOther.js index 155b2b9ce5..3bb1a2091f 100644 --- a/tests/baselines/reference/typeGuardOfFormTypeOfOther.js +++ b/tests/baselines/reference/typeGuardOfFormTypeOfOther.js @@ -19,12 +19,6 @@ var c: C; // - when true, removes the primitive types string, number, and boolean from the type of x, or // - when false, has no effect on the type of x. -if (typeof strOrNumOrBool === "Object") { - emptyObj = strOrNumOrBool; // {} -} -else { - var r1: string | number | boolean = strOrNumOrBool; // string | number | boolean -} if (typeof strOrC === "Object") { c = strOrC; // C } @@ -44,15 +38,17 @@ else { var r4: boolean | C = boolOrC; // boolean | C } +// Narrowing occurs only if target type is a subtype of variable type +if (typeof strOrNumOrBool === "Object") { + var q1: string | number | boolean = strOrNumOrBool; // string | number | boolean +} +else { + var q2: string | number | boolean = strOrNumOrBool; // string | number | boolean +} + // A type guard of the form typeof x !== s, where s is a string literal, // - when true, narrows the type of x by typeof x === s when false, or // - when false, narrows the type of x by typeof x === s when true. -if (typeof strOrNumOrBool !== "Object") { - var r1: string | number | boolean = strOrNumOrBool; // string | number | boolean -} -else { - emptyObj = strOrNumOrBool; // {} -} if (typeof strOrC !== "Object") { var r2: string | C = strOrC; // string | C } @@ -70,7 +66,16 @@ if (typeof boolOrC !== "Object") { } else { c = boolOrC; // C -} +} + +// Narrowing occurs only if target type is a subtype of variable type +if (typeof strOrNumOrBool !== "Object") { + var q1: string | number | boolean = strOrNumOrBool; // string | number | boolean +} +else { + var q2: string | number | boolean = strOrNumOrBool; // string | number | boolean +} + //// [typeGuardOfFormTypeOfOther.js] var C = (function () { @@ -95,12 +100,6 @@ var c; // where s is a string literal with any value but 'string', 'number' or 'boolean', // - when true, removes the primitive types string, number, and boolean from the type of x, or // - when false, has no effect on the type of x. -if (typeof strOrNumOrBool === "Object") { - emptyObj = strOrNumOrBool; // {} -} -else { - var r1 = strOrNumOrBool; // string | number | boolean -} if (typeof strOrC === "Object") { c = strOrC; // C } @@ -119,15 +118,16 @@ if (typeof boolOrC === "Object") { else { var r4 = boolOrC; // boolean | C } +// Narrowing occurs only if target type is a subtype of variable type +if (typeof strOrNumOrBool === "Object") { + var q1 = strOrNumOrBool; // string | number | boolean +} +else { + var q2 = strOrNumOrBool; // string | number | boolean +} // A type guard of the form typeof x !== s, where s is a string literal, // - when true, narrows the type of x by typeof x === s when false, or // - when false, narrows the type of x by typeof x === s when true. -if (typeof strOrNumOrBool !== "Object") { - var r1 = strOrNumOrBool; // string | number | boolean -} -else { - emptyObj = strOrNumOrBool; // {} -} if (typeof strOrC !== "Object") { var r2 = strOrC; // string | C } @@ -146,3 +146,10 @@ if (typeof boolOrC !== "Object") { else { c = boolOrC; // C } +// Narrowing occurs only if target type is a subtype of variable type +if (typeof strOrNumOrBool !== "Object") { + var q1 = strOrNumOrBool; // string | number | boolean +} +else { + var q2 = strOrNumOrBool; // string | number | boolean +} diff --git a/tests/baselines/reference/typeGuardOfFormTypeOfOther.types b/tests/baselines/reference/typeGuardOfFormTypeOfOther.types index 729c255b14..04060571f8 100644 --- a/tests/baselines/reference/typeGuardOfFormTypeOfOther.types +++ b/tests/baselines/reference/typeGuardOfFormTypeOfOther.types @@ -48,21 +48,6 @@ var c: C; // - when true, removes the primitive types string, number, and boolean from the type of x, or // - when false, has no effect on the type of x. -if (typeof strOrNumOrBool === "Object") { ->typeof strOrNumOrBool === "Object" : boolean ->typeof strOrNumOrBool : string ->strOrNumOrBool : string | number | boolean - - emptyObj = strOrNumOrBool; // {} ->emptyObj = strOrNumOrBool : {} ->emptyObj : {} ->strOrNumOrBool : {} -} -else { - var r1: string | number | boolean = strOrNumOrBool; // string | number | boolean ->r1 : string | number | boolean ->strOrNumOrBool : string | number | boolean -} if (typeof strOrC === "Object") { >typeof strOrC === "Object" : boolean >typeof strOrC : string @@ -112,24 +97,25 @@ else { >boolOrC : boolean | C } -// A type guard of the form typeof x !== s, where s is a string literal, -// - when true, narrows the type of x by typeof x === s when false, or -// - when false, narrows the type of x by typeof x === s when true. -if (typeof strOrNumOrBool !== "Object") { ->typeof strOrNumOrBool !== "Object" : boolean +// Narrowing occurs only if target type is a subtype of variable type +if (typeof strOrNumOrBool === "Object") { +>typeof strOrNumOrBool === "Object" : boolean >typeof strOrNumOrBool : string >strOrNumOrBool : string | number | boolean - var r1: string | number | boolean = strOrNumOrBool; // string | number | boolean ->r1 : string | number | boolean + var q1: string | number | boolean = strOrNumOrBool; // string | number | boolean +>q1 : string | number | boolean >strOrNumOrBool : string | number | boolean } else { - emptyObj = strOrNumOrBool; // {} ->emptyObj = strOrNumOrBool : {} ->emptyObj : {} ->strOrNumOrBool : {} + var q2: string | number | boolean = strOrNumOrBool; // string | number | boolean +>q2 : string | number | boolean +>strOrNumOrBool : string | number | boolean } + +// A type guard of the form typeof x !== s, where s is a string literal, +// - when true, narrows the type of x by typeof x === s when false, or +// - when false, narrows the type of x by typeof x === s when true. if (typeof strOrC !== "Object") { >typeof strOrC !== "Object" : boolean >typeof strOrC : string @@ -178,3 +164,20 @@ else { >c : C >boolOrC : C } + +// Narrowing occurs only if target type is a subtype of variable type +if (typeof strOrNumOrBool !== "Object") { +>typeof strOrNumOrBool !== "Object" : boolean +>typeof strOrNumOrBool : string +>strOrNumOrBool : string | number | boolean + + var q1: string | number | boolean = strOrNumOrBool; // string | number | boolean +>q1 : string | number | boolean +>strOrNumOrBool : string | number | boolean +} +else { + var q2: string | number | boolean = strOrNumOrBool; // string | number | boolean +>q2 : string | number | boolean +>strOrNumOrBool : string | number | boolean +} + diff --git a/tests/baselines/reference/typeGuardOfFormTypeOfString.js b/tests/baselines/reference/typeGuardOfFormTypeOfString.js index 311f499e17..4f6652c440 100644 --- a/tests/baselines/reference/typeGuardOfFormTypeOfString.js +++ b/tests/baselines/reference/typeGuardOfFormTypeOfString.js @@ -29,12 +29,6 @@ if (typeof strOrBool === "string") { else { bool = strOrBool; // boolean } -if (typeof numOrBool === "string") { - str = numOrBool; // string -} -else { - var x : number | boolean = numOrBool; // number | boolean -} if (typeof strOrNumOrBool === "string") { str = strOrNumOrBool; // string } @@ -48,6 +42,14 @@ else { c = strOrC; // C } +// Narrowing occurs only if target type is a subtype of variable type +if (typeof numOrBool === "string") { + var x1: number | boolean = numOrBool; // number | boolean +} +else { + var x2: number | boolean = numOrBool; // number | boolean +} + // A type guard of the form typeof x !== s, where s is a string literal, // - when true, narrows the type of x by typeof x === s when false, or // - when false, narrows the type of x by typeof x === s when true. @@ -63,12 +65,6 @@ if (typeof strOrBool !== "string") { else { str = strOrBool; // string } -if (typeof numOrBool !== "string") { - var x: number | boolean = numOrBool; // number | boolean -} -else { - str = numOrBool; // string -} if (typeof strOrNumOrBool !== "string") { numOrBool = strOrNumOrBool; // number | boolean } @@ -80,7 +76,16 @@ if (typeof strOrC !== "string") { } else { str = strOrC; // string -} +} + +// Narrowing occurs only if target type is a subtype of variable type +if (typeof numOrBool !== "string") { + var x1: number | boolean = numOrBool; // number | boolean +} +else { + var x2: number | boolean = numOrBool; // number | boolean +} + //// [typeGuardOfFormTypeOfString.js] var C = (function () { @@ -116,12 +121,6 @@ if (typeof strOrBool === "string") { else { bool = strOrBool; // boolean } -if (typeof numOrBool === "string") { - str = numOrBool; // string -} -else { - var x = numOrBool; // number | boolean -} if (typeof strOrNumOrBool === "string") { str = strOrNumOrBool; // string } @@ -134,6 +133,13 @@ if (typeof strOrC === "string") { else { c = strOrC; // C } +// Narrowing occurs only if target type is a subtype of variable type +if (typeof numOrBool === "string") { + var x1 = numOrBool; // number | boolean +} +else { + var x2 = numOrBool; // number | boolean +} // A type guard of the form typeof x !== s, where s is a string literal, // - when true, narrows the type of x by typeof x === s when false, or // - when false, narrows the type of x by typeof x === s when true. @@ -149,12 +155,6 @@ if (typeof strOrBool !== "string") { else { str = strOrBool; // string } -if (typeof numOrBool !== "string") { - var x = numOrBool; // number | boolean -} -else { - str = numOrBool; // string -} if (typeof strOrNumOrBool !== "string") { numOrBool = strOrNumOrBool; // number | boolean } @@ -167,3 +167,10 @@ if (typeof strOrC !== "string") { else { str = strOrC; // string } +// Narrowing occurs only if target type is a subtype of variable type +if (typeof numOrBool !== "string") { + var x1 = numOrBool; // number | boolean +} +else { + var x2 = numOrBool; // number | boolean +} diff --git a/tests/baselines/reference/typeGuardOfFormTypeOfString.types b/tests/baselines/reference/typeGuardOfFormTypeOfString.types index e6d90b74c6..90719fce92 100644 --- a/tests/baselines/reference/typeGuardOfFormTypeOfString.types +++ b/tests/baselines/reference/typeGuardOfFormTypeOfString.types @@ -76,21 +76,6 @@ else { >bool : boolean >strOrBool : boolean } -if (typeof numOrBool === "string") { ->typeof numOrBool === "string" : boolean ->typeof numOrBool : string ->numOrBool : number | boolean - - str = numOrBool; // string ->str = numOrBool : string ->str : string ->numOrBool : string -} -else { - var x : number | boolean = numOrBool; // number | boolean ->x : number | boolean ->numOrBool : number | boolean -} if (typeof strOrNumOrBool === "string") { >typeof strOrNumOrBool === "string" : boolean >typeof strOrNumOrBool : string @@ -124,6 +109,22 @@ else { >strOrC : C } +// Narrowing occurs only if target type is a subtype of variable type +if (typeof numOrBool === "string") { +>typeof numOrBool === "string" : boolean +>typeof numOrBool : string +>numOrBool : number | boolean + + var x1: number | boolean = numOrBool; // number | boolean +>x1 : number | boolean +>numOrBool : number | boolean +} +else { + var x2: number | boolean = numOrBool; // number | boolean +>x2 : number | boolean +>numOrBool : number | boolean +} + // A type guard of the form typeof x !== s, where s is a string literal, // - when true, narrows the type of x by typeof x === s when false, or // - when false, narrows the type of x by typeof x === s when true. @@ -159,21 +160,6 @@ else { >str : string >strOrBool : string } -if (typeof numOrBool !== "string") { ->typeof numOrBool !== "string" : boolean ->typeof numOrBool : string ->numOrBool : number | boolean - - var x: number | boolean = numOrBool; // number | boolean ->x : number | boolean ->numOrBool : number | boolean -} -else { - str = numOrBool; // string ->str = numOrBool : string ->str : string ->numOrBool : string -} if (typeof strOrNumOrBool !== "string") { >typeof strOrNumOrBool !== "string" : boolean >typeof strOrNumOrBool : string @@ -206,3 +192,20 @@ else { >str : string >strOrC : string } + +// Narrowing occurs only if target type is a subtype of variable type +if (typeof numOrBool !== "string") { +>typeof numOrBool !== "string" : boolean +>typeof numOrBool : string +>numOrBool : number | boolean + + var x1: number | boolean = numOrBool; // number | boolean +>x1 : number | boolean +>numOrBool : number | boolean +} +else { + var x2: number | boolean = numOrBool; // number | boolean +>x2 : number | boolean +>numOrBool : number | boolean +} + diff --git a/tests/baselines/reference/typeGuardsDefeat.js b/tests/baselines/reference/typeGuardsDefeat.js index b5e1e0c362..9670c260b5 100644 --- a/tests/baselines/reference/typeGuardsDefeat.js +++ b/tests/baselines/reference/typeGuardsDefeat.js @@ -18,23 +18,24 @@ function foo2(x: number | string) { return x.length; // string } else { - (function f() { - x = 10; - })(); - return x++; // number + var f = function () { + return x * x; + }; } + x = "hello"; + f(); } function foo3(x: number | string) { if (typeof x === "string") { return x.length; // string } else { - (() => { - x = 10; - })(); - return x++; // number + var f = () => x * x; } -} + x = "hello"; + f(); +} + //// [typeGuardsDefeat.js] // Also note that it is possible to defeat a type guard by calling a function that changes the @@ -56,20 +57,20 @@ function foo2(x) { return x.length; // string } else { - (function f() { - x = 10; - })(); - return x++; // number + var f = function () { + return x * x; + }; } + x = "hello"; + f(); } function foo3(x) { if (typeof x === "string") { return x.length; // string } else { - (function () { - x = 10; - })(); - return x++; // number + var f = function () { return x * x; }; } + x = "hello"; + f(); } diff --git a/tests/baselines/reference/typeGuardsDefeat.types b/tests/baselines/reference/typeGuardsDefeat.types index 6c4153cc3e..5daaa75d97 100644 --- a/tests/baselines/reference/typeGuardsDefeat.types +++ b/tests/baselines/reference/typeGuardsDefeat.types @@ -47,21 +47,24 @@ function foo2(x: number | string) { >length : number } else { - (function f() { ->(function f() { x = 10; })() : void ->(function f() { x = 10; }) : () => void ->function f() { x = 10; } : () => void ->f : () => void + var f = function () { +>f : () => number +>function () { return x * x; } : () => number - x = 10; ->x = 10 : number + return x * x; +>x * x : number +>x : number +>x : number + + }; + } + x = "hello"; +>x = "hello" : string >x : string | number - })(); - return x++; // number ->x++ : number ->x : number - } + f(); +>f() : number +>f : () => number } function foo3(x: number | string) { >foo3 : (x: string | number) => number @@ -78,18 +81,19 @@ function foo3(x: number | string) { >length : number } else { - (() => { ->(() => { x = 10; })() : void ->(() => { x = 10; }) : () => void ->() => { x = 10; } : () => void - - x = 10; ->x = 10 : number ->x : string | number - - })(); - return x++; // number ->x++ : number + var f = () => x * x; +>f : () => number +>() => x * x : () => number +>x * x : number +>x : number >x : number } + x = "hello"; +>x = "hello" : string +>x : string | number + + f(); +>f() : number +>f : () => number } + diff --git a/tests/baselines/reference/typeGuardsInFunctionAndModuleBlock.js b/tests/baselines/reference/typeGuardsInFunctionAndModuleBlock.js index 1152cd8d8b..01bd6f267e 100644 --- a/tests/baselines/reference/typeGuardsInFunctionAndModuleBlock.js +++ b/tests/baselines/reference/typeGuardsInFunctionAndModuleBlock.js @@ -5,40 +5,40 @@ function foo(x: number | string | boolean) { return typeof x === "string" ? x : function f() { - var b = x; // new scope - number | boolean | string + var b = x; // number | boolean return typeof x === "boolean" ? x.toString() // boolean - : x.toString(); // number | string + : x.toString(); // number } (); } function foo2(x: number | string | boolean) { return typeof x === "string" ? x : function f(a: number | boolean) { - var b = x; // new scope - number | boolean | string + var b = x; // new scope - number | boolean return typeof x === "boolean" ? x.toString() // boolean - : x.toString(); // number | string + : x.toString(); // number } (x); // x here is narrowed to number | boolean } function foo3(x: number | string | boolean) { return typeof x === "string" ? x : (() => { - var b = x; // new scope - number | boolean | string + var b = x; // new scope - number | boolean return typeof x === "boolean" ? x.toString() // boolean - : x.toString(); // number | string + : x.toString(); // number })(); } function foo4(x: number | string | boolean) { return typeof x === "string" ? x : ((a: number | boolean) => { - var b = x; // new scope - number | boolean | string + var b = x; // new scope - number | boolean return typeof x === "boolean" ? x.toString() // boolean - : x.toString(); // number | string + : x.toString(); // number })(x); // x here is narrowed to number | boolean } module m { @@ -74,26 +74,26 @@ module m1 { // typeguards are scoped in function/module block function foo(x) { return typeof x === "string" ? x : function f() { - var b = x; // new scope - number | boolean | string - return typeof x === "boolean" ? x.toString() : x.toString(); // number | string + var b = x; // number | boolean + return typeof x === "boolean" ? x.toString() : x.toString(); // number }(); } function foo2(x) { return typeof x === "string" ? x : function f(a) { - var b = x; // new scope - number | boolean | string - return typeof x === "boolean" ? x.toString() : x.toString(); // number | string + var b = x; // new scope - number | boolean + return typeof x === "boolean" ? x.toString() : x.toString(); // number }(x); // x here is narrowed to number | boolean } function foo3(x) { return typeof x === "string" ? x : (function () { - var b = x; // new scope - number | boolean | string - return typeof x === "boolean" ? x.toString() : x.toString(); // number | string + var b = x; // new scope - number | boolean + return typeof x === "boolean" ? x.toString() : x.toString(); // number })(); } function foo4(x) { return typeof x === "string" ? x : (function (a) { - var b = x; // new scope - number | boolean | string - return typeof x === "boolean" ? x.toString() : x.toString(); // number | string + var b = x; // new scope - number | boolean + return typeof x === "boolean" ? x.toString() : x.toString(); // number })(x); // x here is narrowed to number | boolean } var m; diff --git a/tests/baselines/reference/typeGuardsInFunctionAndModuleBlock.types b/tests/baselines/reference/typeGuardsInFunctionAndModuleBlock.types index c1ba1a7d63..ec844960f5 100644 --- a/tests/baselines/reference/typeGuardsInFunctionAndModuleBlock.types +++ b/tests/baselines/reference/typeGuardsInFunctionAndModuleBlock.types @@ -6,7 +6,7 @@ function foo(x: number | string | boolean) { >x : string | number | boolean return typeof x === "string" ->typeof x === "string" ? x : function f() { var b = x; // new scope - number | boolean | string return typeof x === "boolean" ? x.toString() // boolean : x.toString(); // number | string } () : string +>typeof x === "string" ? x : function f() { var b = x; // number | boolean return typeof x === "boolean" ? x.toString() // boolean : x.toString(); // number } () : string >typeof x === "string" : boolean >typeof x : string >x : string | number | boolean @@ -15,19 +15,19 @@ function foo(x: number | string | boolean) { >x : string : function f() { ->function f() { var b = x; // new scope - number | boolean | string return typeof x === "boolean" ? x.toString() // boolean : x.toString(); // number | string } () : string ->function f() { var b = x; // new scope - number | boolean | string return typeof x === "boolean" ? x.toString() // boolean : x.toString(); // number | string } : () => string +>function f() { var b = x; // number | boolean return typeof x === "boolean" ? x.toString() // boolean : x.toString(); // number } () : string +>function f() { var b = x; // number | boolean return typeof x === "boolean" ? x.toString() // boolean : x.toString(); // number } : () => string >f : () => string - var b = x; // new scope - number | boolean | string ->b : string | number | boolean ->x : string | number | boolean + var b = x; // number | boolean +>b : number | boolean +>x : number | boolean return typeof x === "boolean" >typeof x === "boolean" ? x.toString() // boolean : x.toString() : string >typeof x === "boolean" : boolean >typeof x : string ->x : string | number | boolean +>x : number | boolean ? x.toString() // boolean >x.toString() : string @@ -35,11 +35,11 @@ function foo(x: number | string | boolean) { >x : boolean >toString : () => string - : x.toString(); // number | string + : x.toString(); // number >x.toString() : string ->x.toString : () => string ->x : string | number ->toString : () => string +>x.toString : (radix?: number) => string +>x : number +>toString : (radix?: number) => string } (); } @@ -48,7 +48,7 @@ function foo2(x: number | string | boolean) { >x : string | number | boolean return typeof x === "string" ->typeof x === "string" ? x : function f(a: number | boolean) { var b = x; // new scope - number | boolean | string return typeof x === "boolean" ? x.toString() // boolean : x.toString(); // number | string } (x) : string +>typeof x === "string" ? x : function f(a: number | boolean) { var b = x; // new scope - number | boolean return typeof x === "boolean" ? x.toString() // boolean : x.toString(); // number } (x) : string >typeof x === "string" : boolean >typeof x : string >x : string | number | boolean @@ -57,20 +57,20 @@ function foo2(x: number | string | boolean) { >x : string : function f(a: number | boolean) { ->function f(a: number | boolean) { var b = x; // new scope - number | boolean | string return typeof x === "boolean" ? x.toString() // boolean : x.toString(); // number | string } (x) : string ->function f(a: number | boolean) { var b = x; // new scope - number | boolean | string return typeof x === "boolean" ? x.toString() // boolean : x.toString(); // number | string } : (a: number | boolean) => string +>function f(a: number | boolean) { var b = x; // new scope - number | boolean return typeof x === "boolean" ? x.toString() // boolean : x.toString(); // number } (x) : string +>function f(a: number | boolean) { var b = x; // new scope - number | boolean return typeof x === "boolean" ? x.toString() // boolean : x.toString(); // number } : (a: number | boolean) => string >f : (a: number | boolean) => string >a : number | boolean - var b = x; // new scope - number | boolean | string ->b : string | number | boolean ->x : string | number | boolean + var b = x; // new scope - number | boolean +>b : number | boolean +>x : number | boolean return typeof x === "boolean" >typeof x === "boolean" ? x.toString() // boolean : x.toString() : string >typeof x === "boolean" : boolean >typeof x : string ->x : string | number | boolean +>x : number | boolean ? x.toString() // boolean >x.toString() : string @@ -78,11 +78,11 @@ function foo2(x: number | string | boolean) { >x : boolean >toString : () => string - : x.toString(); // number | string + : x.toString(); // number >x.toString() : string ->x.toString : () => string ->x : string | number ->toString : () => string +>x.toString : (radix?: number) => string +>x : number +>toString : (radix?: number) => string } (x); // x here is narrowed to number | boolean >x : number | boolean @@ -92,7 +92,7 @@ function foo3(x: number | string | boolean) { >x : string | number | boolean return typeof x === "string" ->typeof x === "string" ? x : (() => { var b = x; // new scope - number | boolean | string return typeof x === "boolean" ? x.toString() // boolean : x.toString(); // number | string })() : string +>typeof x === "string" ? x : (() => { var b = x; // new scope - number | boolean return typeof x === "boolean" ? x.toString() // boolean : x.toString(); // number })() : string >typeof x === "string" : boolean >typeof x : string >x : string | number | boolean @@ -101,19 +101,19 @@ function foo3(x: number | string | boolean) { >x : string : (() => { ->(() => { var b = x; // new scope - number | boolean | string return typeof x === "boolean" ? x.toString() // boolean : x.toString(); // number | string })() : string ->(() => { var b = x; // new scope - number | boolean | string return typeof x === "boolean" ? x.toString() // boolean : x.toString(); // number | string }) : () => string ->() => { var b = x; // new scope - number | boolean | string return typeof x === "boolean" ? x.toString() // boolean : x.toString(); // number | string } : () => string +>(() => { var b = x; // new scope - number | boolean return typeof x === "boolean" ? x.toString() // boolean : x.toString(); // number })() : string +>(() => { var b = x; // new scope - number | boolean return typeof x === "boolean" ? x.toString() // boolean : x.toString(); // number }) : () => string +>() => { var b = x; // new scope - number | boolean return typeof x === "boolean" ? x.toString() // boolean : x.toString(); // number } : () => string - var b = x; // new scope - number | boolean | string ->b : string | number | boolean ->x : string | number | boolean + var b = x; // new scope - number | boolean +>b : number | boolean +>x : number | boolean return typeof x === "boolean" >typeof x === "boolean" ? x.toString() // boolean : x.toString() : string >typeof x === "boolean" : boolean >typeof x : string ->x : string | number | boolean +>x : number | boolean ? x.toString() // boolean >x.toString() : string @@ -121,11 +121,11 @@ function foo3(x: number | string | boolean) { >x : boolean >toString : () => string - : x.toString(); // number | string + : x.toString(); // number >x.toString() : string ->x.toString : () => string ->x : string | number ->toString : () => string +>x.toString : (radix?: number) => string +>x : number +>toString : (radix?: number) => string })(); } @@ -134,7 +134,7 @@ function foo4(x: number | string | boolean) { >x : string | number | boolean return typeof x === "string" ->typeof x === "string" ? x : ((a: number | boolean) => { var b = x; // new scope - number | boolean | string return typeof x === "boolean" ? x.toString() // boolean : x.toString(); // number | string })(x) : string +>typeof x === "string" ? x : ((a: number | boolean) => { var b = x; // new scope - number | boolean return typeof x === "boolean" ? x.toString() // boolean : x.toString(); // number })(x) : string >typeof x === "string" : boolean >typeof x : string >x : string | number | boolean @@ -143,20 +143,20 @@ function foo4(x: number | string | boolean) { >x : string : ((a: number | boolean) => { ->((a: number | boolean) => { var b = x; // new scope - number | boolean | string return typeof x === "boolean" ? x.toString() // boolean : x.toString(); // number | string })(x) : string ->((a: number | boolean) => { var b = x; // new scope - number | boolean | string return typeof x === "boolean" ? x.toString() // boolean : x.toString(); // number | string }) : (a: number | boolean) => string ->(a: number | boolean) => { var b = x; // new scope - number | boolean | string return typeof x === "boolean" ? x.toString() // boolean : x.toString(); // number | string } : (a: number | boolean) => string +>((a: number | boolean) => { var b = x; // new scope - number | boolean return typeof x === "boolean" ? x.toString() // boolean : x.toString(); // number })(x) : string +>((a: number | boolean) => { var b = x; // new scope - number | boolean return typeof x === "boolean" ? x.toString() // boolean : x.toString(); // number }) : (a: number | boolean) => string +>(a: number | boolean) => { var b = x; // new scope - number | boolean return typeof x === "boolean" ? x.toString() // boolean : x.toString(); // number } : (a: number | boolean) => string >a : number | boolean - var b = x; // new scope - number | boolean | string ->b : string | number | boolean ->x : string | number | boolean + var b = x; // new scope - number | boolean +>b : number | boolean +>x : number | boolean return typeof x === "boolean" >typeof x === "boolean" ? x.toString() // boolean : x.toString() : string >typeof x === "boolean" : boolean >typeof x : string ->x : string | number | boolean +>x : number | boolean ? x.toString() // boolean >x.toString() : string @@ -164,11 +164,11 @@ function foo4(x: number | string | boolean) { >x : boolean >toString : () => string - : x.toString(); // number | string + : x.toString(); // number >x.toString() : string ->x.toString : () => string ->x : string | number ->toString : () => string +>x.toString : (radix?: number) => string +>x : number +>toString : (radix?: number) => string })(x); // x here is narrowed to number | boolean >x : number | boolean diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfBoolean.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfBoolean.ts index dc6166852a..fb699ce8ce 100644 --- a/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfBoolean.ts +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfBoolean.ts @@ -16,12 +16,6 @@ var c: C; // where s is a string literal with the value 'string', 'number', or 'boolean', // - when true, narrows the type of x to the given primitive type, or // - when false, removes the primitive type from the type of x. -if (typeof strOrNum === "boolean") { - bool = strOrNum; // boolean -} -else { - var z: string | number = strOrNum; // string | number -} if (typeof strOrBool === "boolean") { bool = strOrBool; // boolean } @@ -47,15 +41,18 @@ else { c = boolOrC; // C } +// Narrowing occurs only if target type is a subtype of variable type +if (typeof strOrNum === "boolean") { + var z1: string | number = strOrNum; // string | number +} +else { + var z2: string | number = strOrNum; // string | number +} + + // A type guard of the form typeof x !== s, where s is a string literal, // - when true, narrows the type of x by typeof x === s when false, or // - when false, narrows the type of x by typeof x === s when true. -if (typeof strOrNum !== "boolean") { - var z: string | number = strOrNum; // string | number -} -else { - bool = strOrNum; // boolean -} if (typeof strOrBool !== "boolean") { str = strOrBool; // string } @@ -79,4 +76,12 @@ if (typeof boolOrC !== "boolean") { } else { bool = boolOrC; // boolean -} \ No newline at end of file +} + +// Narrowing occurs only if target type is a subtype of variable type +if (typeof strOrNum !== "boolean") { + var z1: string | number = strOrNum; // string | number +} +else { + var z2: string | number = strOrNum; // string | number +} diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfNumber.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfNumber.ts index b05e5a3a00..2868b11407 100644 --- a/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfNumber.ts +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfNumber.ts @@ -22,12 +22,6 @@ if (typeof strOrNum === "number") { else { str === strOrNum; // string } -if (typeof strOrBool === "number") { - num = strOrBool; // number -} -else { - var y: string | boolean = strOrBool; // string | boolean -} if (typeof numOrBool === "number") { num = numOrBool; // number } @@ -47,6 +41,14 @@ else { c = numOrC; // C } +// Narrowing occurs only if target type is a subtype of variable type +if (typeof strOrBool === "number") { + var y1: string | boolean = strOrBool; // string | boolean +} +else { + var y2: string | boolean = strOrBool; // string | boolean +} + // A type guard of the form typeof x !== s, where s is a string literal, // - when true, narrows the type of x by typeof x === s when false, or // - when false, narrows the type of x by typeof x === s when true. @@ -56,12 +58,6 @@ if (typeof strOrNum !== "number") { else { num = strOrNum; // number } -if (typeof strOrBool !== "number") { - var y: string | boolean = strOrBool; // string | boolean -} -else { - num = strOrBool; // number -} if (typeof numOrBool !== "number") { var x: number | boolean = numOrBool; // number | boolean } @@ -79,4 +75,12 @@ if (typeof numOrC !== "number") { } else { num = numOrC; // number -} \ No newline at end of file +} + +// Narrowing occurs only if target type is a subtype of variable type +if (typeof strOrBool !== "number") { + var y1: string | boolean = strOrBool; // string | boolean +} +else { + var y2: string | boolean = strOrBool; // string | boolean +} diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfOther.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfOther.ts index 18109890c2..9d7d555fc1 100644 --- a/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfOther.ts +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfOther.ts @@ -18,12 +18,6 @@ var c: C; // - when true, removes the primitive types string, number, and boolean from the type of x, or // - when false, has no effect on the type of x. -if (typeof strOrNumOrBool === "Object") { - emptyObj = strOrNumOrBool; // {} -} -else { - var r1: string | number | boolean = strOrNumOrBool; // string | number | boolean -} if (typeof strOrC === "Object") { c = strOrC; // C } @@ -43,15 +37,17 @@ else { var r4: boolean | C = boolOrC; // boolean | C } +// Narrowing occurs only if target type is a subtype of variable type +if (typeof strOrNumOrBool === "Object") { + var q1: string | number | boolean = strOrNumOrBool; // string | number | boolean +} +else { + var q2: string | number | boolean = strOrNumOrBool; // string | number | boolean +} + // A type guard of the form typeof x !== s, where s is a string literal, // - when true, narrows the type of x by typeof x === s when false, or // - when false, narrows the type of x by typeof x === s when true. -if (typeof strOrNumOrBool !== "Object") { - var r1: string | number | boolean = strOrNumOrBool; // string | number | boolean -} -else { - emptyObj = strOrNumOrBool; // {} -} if (typeof strOrC !== "Object") { var r2: string | C = strOrC; // string | C } @@ -69,4 +65,12 @@ if (typeof boolOrC !== "Object") { } else { c = boolOrC; // C -} \ No newline at end of file +} + +// Narrowing occurs only if target type is a subtype of variable type +if (typeof strOrNumOrBool !== "Object") { + var q1: string | number | boolean = strOrNumOrBool; // string | number | boolean +} +else { + var q2: string | number | boolean = strOrNumOrBool; // string | number | boolean +} diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfString.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfString.ts index 8c6bbdaf90..a356858e6c 100644 --- a/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfString.ts +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfString.ts @@ -28,12 +28,6 @@ if (typeof strOrBool === "string") { else { bool = strOrBool; // boolean } -if (typeof numOrBool === "string") { - str = numOrBool; // string -} -else { - var x : number | boolean = numOrBool; // number | boolean -} if (typeof strOrNumOrBool === "string") { str = strOrNumOrBool; // string } @@ -47,6 +41,14 @@ else { c = strOrC; // C } +// Narrowing occurs only if target type is a subtype of variable type +if (typeof numOrBool === "string") { + var x1: number | boolean = numOrBool; // number | boolean +} +else { + var x2: number | boolean = numOrBool; // number | boolean +} + // A type guard of the form typeof x !== s, where s is a string literal, // - when true, narrows the type of x by typeof x === s when false, or // - when false, narrows the type of x by typeof x === s when true. @@ -62,12 +64,6 @@ if (typeof strOrBool !== "string") { else { str = strOrBool; // string } -if (typeof numOrBool !== "string") { - var x: number | boolean = numOrBool; // number | boolean -} -else { - str = numOrBool; // string -} if (typeof strOrNumOrBool !== "string") { numOrBool = strOrNumOrBool; // number | boolean } @@ -79,4 +75,12 @@ if (typeof strOrC !== "string") { } else { str = strOrC; // string -} \ No newline at end of file +} + +// Narrowing occurs only if target type is a subtype of variable type +if (typeof numOrBool !== "string") { + var x1: number | boolean = numOrBool; // number | boolean +} +else { + var x2: number | boolean = numOrBool; // number | boolean +} diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardsDefeat.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardsDefeat.ts index 9c78e72539..0d4fbbc96f 100644 --- a/tests/cases/conformance/expressions/typeGuards/typeGuardsDefeat.ts +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardsDefeat.ts @@ -17,20 +17,20 @@ function foo2(x: number | string) { return x.length; // string } else { - (function f() { - x = 10; - })(); - return x++; // number + var f = function () { + return x * x; + }; } + x = "hello"; + f(); } function foo3(x: number | string) { if (typeof x === "string") { return x.length; // string } else { - (() => { - x = 10; - })(); - return x++; // number + var f = () => x * x; } -} \ No newline at end of file + x = "hello"; + f(); +} diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardsInFunctionAndModuleBlock.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardsInFunctionAndModuleBlock.ts index 244e9f8fa6..2727375294 100644 --- a/tests/cases/conformance/expressions/typeGuards/typeGuardsInFunctionAndModuleBlock.ts +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardsInFunctionAndModuleBlock.ts @@ -4,40 +4,40 @@ function foo(x: number | string | boolean) { return typeof x === "string" ? x : function f() { - var b = x; // new scope - number | boolean | string + var b = x; // number | boolean return typeof x === "boolean" ? x.toString() // boolean - : x.toString(); // number | string + : x.toString(); // number } (); } function foo2(x: number | string | boolean) { return typeof x === "string" ? x : function f(a: number | boolean) { - var b = x; // new scope - number | boolean | string + var b = x; // new scope - number | boolean return typeof x === "boolean" ? x.toString() // boolean - : x.toString(); // number | string + : x.toString(); // number } (x); // x here is narrowed to number | boolean } function foo3(x: number | string | boolean) { return typeof x === "string" ? x : (() => { - var b = x; // new scope - number | boolean | string + var b = x; // new scope - number | boolean return typeof x === "boolean" ? x.toString() // boolean - : x.toString(); // number | string + : x.toString(); // number })(); } function foo4(x: number | string | boolean) { return typeof x === "string" ? x : ((a: number | boolean) => { - var b = x; // new scope - number | boolean | string + var b = x; // new scope - number | boolean return typeof x === "boolean" ? x.toString() // boolean - : x.toString(); // number | string + : x.toString(); // number })(x); // x here is narrowed to number | boolean } module m {