From 7634f741d944dcd45fb83f0dfd594ecda49d2bfd Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 3 Nov 2014 09:06:40 -0800 Subject: [PATCH 01/15] Conformance tests for array element type of tuple is union type of tuple element types --- .../reference/castingTuple.errors.txt | 19 ++-- tests/baselines/reference/castingTuple.js | 15 +++- .../contextualTypeWithTuple.errors.txt | 37 ++++++-- .../reference/contextualTypeWithTuple.js | 31 ++++++- tests/baselines/reference/indexerWithTuple.js | 49 ++++++++-- .../reference/indexerWithTuple.types | 90 ++++++++++++++++++- .../conformance/types/tuple/castingTuple.ts | 8 +- .../types/tuple/contextualTypeWithTuple.ts | 12 +++ .../types/tuple/indexerWithTuple.ts | 25 +++++- 9 files changed, 251 insertions(+), 35 deletions(-) diff --git a/tests/baselines/reference/castingTuple.errors.txt b/tests/baselines/reference/castingTuple.errors.txt index f4efed6f1d1..98be259964d 100644 --- a/tests/baselines/reference/castingTuple.errors.txt +++ b/tests/baselines/reference/castingTuple.errors.txt @@ -2,19 +2,19 @@ tests/cases/conformance/types/tuple/castingTuple.ts(13,23): error TS2352: Neithe Property '2' is missing in type '[number, string]'. tests/cases/conformance/types/tuple/castingTuple.ts(16,21): error TS2352: Neither type '[C, D]' nor type '[C, D, A]' is assignable to the other. Property '2' is missing in type '[C, D]'. -tests/cases/conformance/types/tuple/castingTuple.ts(24,10): error TS2352: Neither type '[number, string]' nor type '[number, number]' is assignable to the other. +tests/cases/conformance/types/tuple/castingTuple.ts(28,10): error TS2352: Neither type '[number, string]' nor type '[number, number]' is assignable to the other. Types of property '1' are incompatible. Type 'string' is not assignable to type 'number'. -tests/cases/conformance/types/tuple/castingTuple.ts(25,10): error TS2352: Neither type '[C, D]' nor type '[A, I]' is assignable to the other. +tests/cases/conformance/types/tuple/castingTuple.ts(29,10): error TS2352: Neither type '[C, D]' nor type '[A, I]' is assignable to the other. Types of property '0' are incompatible. Type 'C' is not assignable to type 'A'. -tests/cases/conformance/types/tuple/castingTuple.ts(26,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'array1' must be of type '{}[]', but here has type 'number[]'. -tests/cases/conformance/types/tuple/castingTuple.ts(26,14): error TS2352: Neither type '[number, string]' nor type 'number[]' is assignable to the other. +tests/cases/conformance/types/tuple/castingTuple.ts(30,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'array1' must be of type '{}[]', but here has type 'number[]'. +tests/cases/conformance/types/tuple/castingTuple.ts(30,14): error TS2352: Neither type '[number, string]' nor type 'number[]' is assignable to the other. Types of property 'pop' are incompatible. Type '() => string | number' is not assignable to type '() => number'. Type 'string | number' is not assignable to type 'number'. Type 'string' is not assignable to type 'number'. -tests/cases/conformance/types/tuple/castingTuple.ts(27,1): error TS2304: Cannot find name 't4'. +tests/cases/conformance/types/tuple/castingTuple.ts(31,1): error TS2304: Cannot find name 't4'. ==== tests/cases/conformance/types/tuple/castingTuple.ts (7 errors) ==== @@ -41,10 +41,14 @@ tests/cases/conformance/types/tuple/castingTuple.ts(27,1): error TS2304: Cannot !!! error TS2352: Neither type '[C, D]' nor type '[C, D, A]' is assignable to the other. !!! error TS2352: Property '2' is missing in type '[C, D]'. var eleFromCDA1 = classCDATuple[2]; // A - var eleFromCDA2 = classCDATuple[5]; // {} + var eleFromCDA2 = classCDATuple[5]; // C | D | A var t10: [E1, E2] = [E1.one, E2.one]; var t11 = <[number, number]>t10; var array1 = <{}[]>emptyObjTuple; + var unionTuple: [C, string | number] = [new C(), "foo"]; + var unionTuple2: [C, string | number, D] = [new C(), "foo", new D()]; + var unionTuple3: [number, string| number] = [10, "foo"]; + var unionTuple4 = <[number, number]>unionTuple3; // error var t3 = <[number, number]>numStrTuple; @@ -68,4 +72,5 @@ tests/cases/conformance/types/tuple/castingTuple.ts(27,1): error TS2304: Cannot !!! error TS2352: Type 'string' is not assignable to type 'number'. t4[2] = 10; ~~ -!!! error TS2304: Cannot find name 't4'. \ No newline at end of file +!!! error TS2304: Cannot find name 't4'. + \ No newline at end of file diff --git a/tests/baselines/reference/castingTuple.js b/tests/baselines/reference/castingTuple.js index 0671062bb4e..fffadcbc070 100644 --- a/tests/baselines/reference/castingTuple.js +++ b/tests/baselines/reference/castingTuple.js @@ -16,16 +16,21 @@ var classCDTuple: [C, D] = [new C(), new D()]; var interfaceIITuple = <[I, I]>classCDTuple; var classCDATuple = <[C, D, A]>classCDTuple; var eleFromCDA1 = classCDATuple[2]; // A -var eleFromCDA2 = classCDATuple[5]; // {} +var eleFromCDA2 = classCDATuple[5]; // C | D | A var t10: [E1, E2] = [E1.one, E2.one]; var t11 = <[number, number]>t10; var array1 = <{}[]>emptyObjTuple; +var unionTuple: [C, string | number] = [new C(), "foo"]; +var unionTuple2: [C, string | number, D] = [new C(), "foo", new D()]; +var unionTuple3: [number, string| number] = [10, "foo"]; +var unionTuple4 = <[number, number]>unionTuple3; // error var t3 = <[number, number]>numStrTuple; var t9 = <[A, I]>classCDTuple; var array1 = numStrTuple; -t4[2] = 10; +t4[2] = 10; + //// [castingTuple.js] var __extends = this.__extends || function (d, b) { @@ -84,10 +89,14 @@ var classCDTuple = [new C(), new D()]; var interfaceIITuple = classCDTuple; var classCDATuple = classCDTuple; var eleFromCDA1 = classCDATuple[2]; // A -var eleFromCDA2 = classCDATuple[5]; // {} +var eleFromCDA2 = classCDATuple[5]; // C | D | A var t10 = [0 /* one */, 0 /* one */]; var t11 = t10; var array1 = emptyObjTuple; +var unionTuple = [new C(), "foo"]; +var unionTuple2 = [new C(), "foo", new D()]; +var unionTuple3 = [10, "foo"]; +var unionTuple4 = unionTuple3; // error var t3 = numStrTuple; var t9 = classCDTuple; diff --git a/tests/baselines/reference/contextualTypeWithTuple.errors.txt b/tests/baselines/reference/contextualTypeWithTuple.errors.txt index d093e176455..32e368b0f88 100644 --- a/tests/baselines/reference/contextualTypeWithTuple.errors.txt +++ b/tests/baselines/reference/contextualTypeWithTuple.errors.txt @@ -4,21 +4,27 @@ tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(3,5): error TS232 Type 'string | number | boolean' is not assignable to type 'string | number'. Type 'boolean' is not assignable to type 'string | number'. Type 'boolean' is not assignable to type 'number'. -tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(8,1): error TS2323: Type '[number, string, boolean]' is not assignable to type '[number, string]'. -tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(11,1): error TS2323: Type '[{}, number]' is not assignable to type '[{ a: string; }, number]'. +tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(15,1): error TS2323: Type '[number, string, boolean]' is not assignable to type '[number, string]'. +tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(18,1): error TS2323: Type '[{}, number]' is not assignable to type '[{ a: string; }, number]'. Types of property '0' are incompatible. Type '{}' is not assignable to type '{ a: string; }'. Property 'a' is missing in type '{}'. -tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(12,1): error TS2323: Type '[number, string]' is not assignable to type '[number, string, boolean]'. +tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(19,1): error TS2323: Type '[number, string]' is not assignable to type '[number, string, boolean]'. Property '2' is missing in type '[number, string]'. -tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(13,5): error TS2323: Type '[string, string, number]' is not assignable to type '[string, string]'. +tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(20,5): error TS2323: Type '[string, string, number]' is not assignable to type '[string, string]'. Types of property 'pop' are incompatible. Type '() => string | number' is not assignable to type '() => string'. Type 'string | number' is not assignable to type 'string'. Type 'number' is not assignable to type 'string'. +tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(24,1): error TS2323: Type '[C, string | number]' is not assignable to type '[C, string | number, D]'. + Property '2' is missing in type '[C, string | number]'. +tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(25,1): error TS2323: Type '[number, string | number]' is not assignable to type '[number, string]'. + Types of property '1' are incompatible. + Type 'string | number' is not assignable to type 'string'. + Type 'number' is not assignable to type 'string'. -==== tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts (5 errors) ==== +==== tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts (7 errors) ==== // no error var numStrTuple: [number, string] = [5, "hello"]; var numStrTuple2: [number, string] = [5, "foo", true]; @@ -32,6 +38,13 @@ tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(13,5): error TS23 var numStrBoolTuple: [number, string, boolean] = [5, "foo", true]; var objNumTuple: [{ a: string }, number] = [{ a: "world" }, 5]; var strTupleTuple: [string, [number, {}]] = ["bar", [5, { x: 1, y: 1 }]]; + class C { } + class D { } + var unionTuple: [C, string | number] = [new C(), "foo"]; + var unionTuple1: [C, string | number] = [new C(), "foo"]; + var unionTuple2: [C, string | number, D] = [new C(), "foo", new D()]; + var unionTuple3: [number, string| number] = [10, "foo"]; + numStrTuple = numStrTuple2; numStrTuple = numStrBoolTuple; ~~~~~~~~~~~ @@ -55,4 +68,16 @@ tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(13,5): error TS23 !!! error TS2323: Type '() => string | number' is not assignable to type '() => string'. !!! error TS2323: Type 'string | number' is not assignable to type 'string'. !!! error TS2323: Type 'number' is not assignable to type 'string'. - \ No newline at end of file + + unionTuple = unionTuple1; + unionTuple = unionTuple2; + unionTuple2 = unionTuple; + ~~~~~~~~~~~ +!!! error TS2323: Type '[C, string | number]' is not assignable to type '[C, string | number, D]'. +!!! error TS2323: Property '2' is missing in type '[C, string | number]'. + numStrTuple = unionTuple3; + ~~~~~~~~~~~ +!!! error TS2323: Type '[number, string | number]' is not assignable to type '[number, string]'. +!!! error TS2323: Types of property '1' are incompatible. +!!! error TS2323: Type 'string | number' is not assignable to type 'string'. +!!! error TS2323: Type 'number' is not assignable to type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/contextualTypeWithTuple.js b/tests/baselines/reference/contextualTypeWithTuple.js index 61a2df5d8ce..cfcdd13f7d0 100644 --- a/tests/baselines/reference/contextualTypeWithTuple.js +++ b/tests/baselines/reference/contextualTypeWithTuple.js @@ -5,6 +5,13 @@ var numStrTuple2: [number, string] = [5, "foo", true]; var numStrBoolTuple: [number, string, boolean] = [5, "foo", true]; var objNumTuple: [{ a: string }, number] = [{ a: "world" }, 5]; var strTupleTuple: [string, [number, {}]] = ["bar", [5, { x: 1, y: 1 }]]; +class C { } +class D { } +var unionTuple: [C, string | number] = [new C(), "foo"]; +var unionTuple1: [C, string | number] = [new C(), "foo"]; +var unionTuple2: [C, string | number, D] = [new C(), "foo", new D()]; +var unionTuple3: [number, string| number] = [10, "foo"]; + numStrTuple = numStrTuple2; numStrTuple = numStrBoolTuple; @@ -12,7 +19,11 @@ numStrTuple = numStrBoolTuple; objNumTuple = [ {}, 5]; numStrBoolTuple = numStrTuple; var strStrTuple: [string, string] = ["foo", "bar", 5]; - + +unionTuple = unionTuple1; +unionTuple = unionTuple2; +unionTuple2 = unionTuple; +numStrTuple = unionTuple3; //// [contextualTypeWithTuple.js] // no error @@ -21,9 +32,27 @@ var numStrTuple2 = [5, "foo", true]; var numStrBoolTuple = [5, "foo", true]; var objNumTuple = [{ a: "world" }, 5]; var strTupleTuple = ["bar", [5, { x: 1, y: 1 }]]; +var C = (function () { + function C() { + } + return C; +})(); +var D = (function () { + function D() { + } + return D; +})(); +var unionTuple = [new C(), "foo"]; +var unionTuple1 = [new C(), "foo"]; +var unionTuple2 = [new C(), "foo", new D()]; +var unionTuple3 = [10, "foo"]; numStrTuple = numStrTuple2; numStrTuple = numStrBoolTuple; // error objNumTuple = [{}, 5]; numStrBoolTuple = numStrTuple; var strStrTuple = ["foo", "bar", 5]; +unionTuple = unionTuple1; +unionTuple = unionTuple2; +unionTuple2 = unionTuple; +numStrTuple = unionTuple3; diff --git a/tests/baselines/reference/indexerWithTuple.js b/tests/baselines/reference/indexerWithTuple.js index fc82716ba05..91d90792e6d 100644 --- a/tests/baselines/reference/indexerWithTuple.js +++ b/tests/baselines/reference/indexerWithTuple.js @@ -1,32 +1,65 @@ //// [indexerWithTuple.ts] var strNumTuple: [string, number] = ["foo", 10]; var numTupleTuple: [number, [string, number]] = [10, ["bar", 20]]; +var unionTuple1: [number, string| number] = [10, "foo"]; +var unionTuple2: [boolean, string| number] = [true, "foo"]; // no error var idx0 = 0; var idx1 = 1; var ele10 = strNumTuple[0]; // string var ele11 = strNumTuple[1]; // number -var ele12 = strNumTuple[2]; // {} -var ele13 = strNumTuple[idx0]; // {} -var ele14 = strNumTuple[idx1]; // {} +var ele12 = strNumTuple[2]; // string | number +var ele13 = strNumTuple[idx0]; // string | number +var ele14 = strNumTuple[idx1]; // string | number var ele15 = strNumTuple["0"]; // string var ele16 = strNumTuple["1"]; // number var strNumTuple1 = numTupleTuple[1]; //[string, number]; -var ele17 = numTupleTuple[2]; // {} +var ele17 = numTupleTuple[2]; // number | [string, number] +var eleUnion10 = unionTuple1[0]; // number +var eleUnion11 = unionTuple1[1]; // string | number +var eleUnion12 = unionTuple1[2]; // string | number +var eleUnion13 = unionTuple1[idx0]; // string | number +var eleUnion14 = unionTuple1[idx1]; // string | number +var eleUnion15 = unionTuple1["0"]; // number +var eleUnion16 = unionTuple1["1"]; // string | number + +var eleUnion20 = unionTuple2[0]; // boolean +var eleUnion21 = unionTuple2[1]; // string | number +var eleUnion22 = unionTuple2[2]; // string | number | boolean +var eleUnion23 = unionTuple2[idx0]; // string | number | boolean +var eleUnion24 = unionTuple2[idx1]; // string | number | boolean +var eleUnion25 = unionTuple2["0"]; // boolean +var eleUnion26 = unionTuple2["1"]; // string | number //// [indexerWithTuple.js] var strNumTuple = ["foo", 10]; var numTupleTuple = [10, ["bar", 20]]; +var unionTuple1 = [10, "foo"]; +var unionTuple2 = [true, "foo"]; // no error var idx0 = 0; var idx1 = 1; var ele10 = strNumTuple[0]; // string var ele11 = strNumTuple[1]; // number -var ele12 = strNumTuple[2]; // {} -var ele13 = strNumTuple[idx0]; // {} -var ele14 = strNumTuple[idx1]; // {} +var ele12 = strNumTuple[2]; // string | number +var ele13 = strNumTuple[idx0]; // string | number +var ele14 = strNumTuple[idx1]; // string | number var ele15 = strNumTuple["0"]; // string var ele16 = strNumTuple["1"]; // number var strNumTuple1 = numTupleTuple[1]; //[string, number]; -var ele17 = numTupleTuple[2]; // {} +var ele17 = numTupleTuple[2]; // number | [string, number] +var eleUnion10 = unionTuple1[0]; // number +var eleUnion11 = unionTuple1[1]; // string | number +var eleUnion12 = unionTuple1[2]; // string | number +var eleUnion13 = unionTuple1[idx0]; // string | number +var eleUnion14 = unionTuple1[idx1]; // string | number +var eleUnion15 = unionTuple1["0"]; // number +var eleUnion16 = unionTuple1["1"]; // string | number +var eleUnion20 = unionTuple2[0]; // boolean +var eleUnion21 = unionTuple2[1]; // string | number +var eleUnion22 = unionTuple2[2]; // string | number | boolean +var eleUnion23 = unionTuple2[idx0]; // string | number | boolean +var eleUnion24 = unionTuple2[idx1]; // string | number | boolean +var eleUnion25 = unionTuple2["0"]; // boolean +var eleUnion26 = unionTuple2["1"]; // string | number diff --git a/tests/baselines/reference/indexerWithTuple.types b/tests/baselines/reference/indexerWithTuple.types index 28053a33081..75b89ca6088 100644 --- a/tests/baselines/reference/indexerWithTuple.types +++ b/tests/baselines/reference/indexerWithTuple.types @@ -8,6 +8,14 @@ var numTupleTuple: [number, [string, number]] = [10, ["bar", 20]]; >[10, ["bar", 20]] : [number, [string, number]] >["bar", 20] : [string, number] +var unionTuple1: [number, string| number] = [10, "foo"]; +>unionTuple1 : [number, string | number] +>[10, "foo"] : [number, string] + +var unionTuple2: [boolean, string| number] = [true, "foo"]; +>unionTuple2 : [boolean, string | number] +>[true, "foo"] : [boolean, string] + // no error var idx0 = 0; >idx0 : number @@ -25,18 +33,18 @@ var ele11 = strNumTuple[1]; // number >strNumTuple[1] : number >strNumTuple : [string, number] -var ele12 = strNumTuple[2]; // {} +var ele12 = strNumTuple[2]; // string | number >ele12 : string | number >strNumTuple[2] : string | number >strNumTuple : [string, number] -var ele13 = strNumTuple[idx0]; // {} +var ele13 = strNumTuple[idx0]; // string | number >ele13 : string | number >strNumTuple[idx0] : string | number >strNumTuple : [string, number] >idx0 : number -var ele14 = strNumTuple[idx1]; // {} +var ele14 = strNumTuple[idx1]; // string | number >ele14 : string | number >strNumTuple[idx1] : string | number >strNumTuple : [string, number] @@ -57,8 +65,82 @@ var strNumTuple1 = numTupleTuple[1]; //[string, number]; >numTupleTuple[1] : [string, number] >numTupleTuple : [number, [string, number]] -var ele17 = numTupleTuple[2]; // {} +var ele17 = numTupleTuple[2]; // number | [string, number] >ele17 : number | [string, number] >numTupleTuple[2] : number | [string, number] >numTupleTuple : [number, [string, number]] +var eleUnion10 = unionTuple1[0]; // number +>eleUnion10 : number +>unionTuple1[0] : number +>unionTuple1 : [number, string | number] + +var eleUnion11 = unionTuple1[1]; // string | number +>eleUnion11 : string | number +>unionTuple1[1] : string | number +>unionTuple1 : [number, string | number] + +var eleUnion12 = unionTuple1[2]; // string | number +>eleUnion12 : string | number +>unionTuple1[2] : string | number +>unionTuple1 : [number, string | number] + +var eleUnion13 = unionTuple1[idx0]; // string | number +>eleUnion13 : string | number +>unionTuple1[idx0] : string | number +>unionTuple1 : [number, string | number] +>idx0 : number + +var eleUnion14 = unionTuple1[idx1]; // string | number +>eleUnion14 : string | number +>unionTuple1[idx1] : string | number +>unionTuple1 : [number, string | number] +>idx1 : number + +var eleUnion15 = unionTuple1["0"]; // number +>eleUnion15 : number +>unionTuple1["0"] : number +>unionTuple1 : [number, string | number] + +var eleUnion16 = unionTuple1["1"]; // string | number +>eleUnion16 : string | number +>unionTuple1["1"] : string | number +>unionTuple1 : [number, string | number] + +var eleUnion20 = unionTuple2[0]; // boolean +>eleUnion20 : boolean +>unionTuple2[0] : boolean +>unionTuple2 : [boolean, string | number] + +var eleUnion21 = unionTuple2[1]; // string | number +>eleUnion21 : string | number +>unionTuple2[1] : string | number +>unionTuple2 : [boolean, string | number] + +var eleUnion22 = unionTuple2[2]; // string | number | boolean +>eleUnion22 : string | number | boolean +>unionTuple2[2] : string | number | boolean +>unionTuple2 : [boolean, string | number] + +var eleUnion23 = unionTuple2[idx0]; // string | number | boolean +>eleUnion23 : string | number | boolean +>unionTuple2[idx0] : string | number | boolean +>unionTuple2 : [boolean, string | number] +>idx0 : number + +var eleUnion24 = unionTuple2[idx1]; // string | number | boolean +>eleUnion24 : string | number | boolean +>unionTuple2[idx1] : string | number | boolean +>unionTuple2 : [boolean, string | number] +>idx1 : number + +var eleUnion25 = unionTuple2["0"]; // boolean +>eleUnion25 : boolean +>unionTuple2["0"] : boolean +>unionTuple2 : [boolean, string | number] + +var eleUnion26 = unionTuple2["1"]; // string | number +>eleUnion26 : string | number +>unionTuple2["1"] : string | number +>unionTuple2 : [boolean, string | number] + diff --git a/tests/cases/conformance/types/tuple/castingTuple.ts b/tests/cases/conformance/types/tuple/castingTuple.ts index f154e5f00c8..cf5c58af346 100644 --- a/tests/cases/conformance/types/tuple/castingTuple.ts +++ b/tests/cases/conformance/types/tuple/castingTuple.ts @@ -15,13 +15,17 @@ var classCDTuple: [C, D] = [new C(), new D()]; var interfaceIITuple = <[I, I]>classCDTuple; var classCDATuple = <[C, D, A]>classCDTuple; var eleFromCDA1 = classCDATuple[2]; // A -var eleFromCDA2 = classCDATuple[5]; // {} +var eleFromCDA2 = classCDATuple[5]; // C | D | A var t10: [E1, E2] = [E1.one, E2.one]; var t11 = <[number, number]>t10; var array1 = <{}[]>emptyObjTuple; +var unionTuple: [C, string | number] = [new C(), "foo"]; +var unionTuple2: [C, string | number, D] = [new C(), "foo", new D()]; +var unionTuple3: [number, string| number] = [10, "foo"]; +var unionTuple4 = <[number, number]>unionTuple3; // error var t3 = <[number, number]>numStrTuple; var t9 = <[A, I]>classCDTuple; var array1 = numStrTuple; -t4[2] = 10; \ No newline at end of file +t4[2] = 10; diff --git a/tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts b/tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts index 7e9575d7f82..9600ebcd671 100644 --- a/tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts +++ b/tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts @@ -4,6 +4,13 @@ var numStrTuple2: [number, string] = [5, "foo", true]; var numStrBoolTuple: [number, string, boolean] = [5, "foo", true]; var objNumTuple: [{ a: string }, number] = [{ a: "world" }, 5]; var strTupleTuple: [string, [number, {}]] = ["bar", [5, { x: 1, y: 1 }]]; +class C { } +class D { } +var unionTuple: [C, string | number] = [new C(), "foo"]; +var unionTuple1: [C, string | number] = [new C(), "foo"]; +var unionTuple2: [C, string | number, D] = [new C(), "foo", new D()]; +var unionTuple3: [number, string| number] = [10, "foo"]; + numStrTuple = numStrTuple2; numStrTuple = numStrBoolTuple; @@ -11,3 +18,8 @@ numStrTuple = numStrBoolTuple; objNumTuple = [ {}, 5]; numStrBoolTuple = numStrTuple; var strStrTuple: [string, string] = ["foo", "bar", 5]; + +unionTuple = unionTuple1; +unionTuple = unionTuple2; +unionTuple2 = unionTuple; +numStrTuple = unionTuple3; \ No newline at end of file diff --git a/tests/cases/conformance/types/tuple/indexerWithTuple.ts b/tests/cases/conformance/types/tuple/indexerWithTuple.ts index 0b51ecd32ee..930ca56402c 100644 --- a/tests/cases/conformance/types/tuple/indexerWithTuple.ts +++ b/tests/cases/conformance/types/tuple/indexerWithTuple.ts @@ -1,15 +1,32 @@ var strNumTuple: [string, number] = ["foo", 10]; var numTupleTuple: [number, [string, number]] = [10, ["bar", 20]]; +var unionTuple1: [number, string| number] = [10, "foo"]; +var unionTuple2: [boolean, string| number] = [true, "foo"]; // no error var idx0 = 0; var idx1 = 1; var ele10 = strNumTuple[0]; // string var ele11 = strNumTuple[1]; // number -var ele12 = strNumTuple[2]; // {} -var ele13 = strNumTuple[idx0]; // {} -var ele14 = strNumTuple[idx1]; // {} +var ele12 = strNumTuple[2]; // string | number +var ele13 = strNumTuple[idx0]; // string | number +var ele14 = strNumTuple[idx1]; // string | number var ele15 = strNumTuple["0"]; // string var ele16 = strNumTuple["1"]; // number var strNumTuple1 = numTupleTuple[1]; //[string, number]; -var ele17 = numTupleTuple[2]; // {} \ No newline at end of file +var ele17 = numTupleTuple[2]; // number | [string, number] +var eleUnion10 = unionTuple1[0]; // number +var eleUnion11 = unionTuple1[1]; // string | number +var eleUnion12 = unionTuple1[2]; // string | number +var eleUnion13 = unionTuple1[idx0]; // string | number +var eleUnion14 = unionTuple1[idx1]; // string | number +var eleUnion15 = unionTuple1["0"]; // number +var eleUnion16 = unionTuple1["1"]; // string | number + +var eleUnion20 = unionTuple2[0]; // boolean +var eleUnion21 = unionTuple2[1]; // string | number +var eleUnion22 = unionTuple2[2]; // string | number | boolean +var eleUnion23 = unionTuple2[idx0]; // string | number | boolean +var eleUnion24 = unionTuple2[idx1]; // string | number | boolean +var eleUnion25 = unionTuple2["0"]; // boolean +var eleUnion26 = unionTuple2["1"]; // string | number \ No newline at end of file From 568049474e3980751376f8b620dfef711ed65c1f Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 3 Nov 2014 09:20:20 -0800 Subject: [PATCH 02/15] =?UTF-8?q?Tests=20to=20check=20equivalency=20of=20u?= =?UTF-8?q?nion=20types=20A=20union=20type=20encompasses=20an=20unordered?= =?UTF-8?q?=20set=20of=20unrelated=20types=20(that=20is,=20types=20that=20?= =?UTF-8?q?aren=E2=80=99t=20subtypes=20of=20each=20other).=20The=20followi?= =?UTF-8?q?ng=20rules=20govern=20union=20types:=20=E2=80=A2=09A=20|=20B=20?= =?UTF-8?q?is=20equivalent=20to=20A=20if=20B=20is=20a=20subtype=20of=20A.?= =?UTF-8?q?=20=E2=80=A2=09A=20|=20B=20is=20equivalent=20to=20B=20|=20A.=20?= =?UTF-8?q?=E2=80=A2=09AB=20|=20C=20is=20equivalent=20to=20A=20|=20BC,=20w?= =?UTF-8?q?here=20AB=20is=20A=20|=20B=20and=20BC=20is=20B=20|=20C.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../reference/unionTypeEquivalence.js | 54 +++++++++++++++++++ .../reference/unionTypeEquivalence.types | 49 +++++++++++++++++ .../types/union/unionTypeEquivalence.ts | 18 +++++++ 3 files changed, 121 insertions(+) create mode 100644 tests/baselines/reference/unionTypeEquivalence.js create mode 100644 tests/baselines/reference/unionTypeEquivalence.types create mode 100644 tests/cases/conformance/types/union/unionTypeEquivalence.ts diff --git a/tests/baselines/reference/unionTypeEquivalence.js b/tests/baselines/reference/unionTypeEquivalence.js new file mode 100644 index 00000000000..3698ecd2f92 --- /dev/null +++ b/tests/baselines/reference/unionTypeEquivalence.js @@ -0,0 +1,54 @@ +//// [unionTypeEquivalence.ts] +// A | B is equivalent to A if B is a subtype of A +class C { } +class D extends C { } +var x: C; +var x : C | D; + +// A | B is equivalent to B | A. +var y: string | number; +var y : number | string; + +// AB | C is equivalent to A | BC, where AB is A | B and BC is B | C. +var z : string | number | boolean; +var z : (string | number) | boolean; +var z : string | (number | boolean); +var AB : string | number; +var BC : number | boolean; +var z1: typeof AB | boolean; +var z1: string | typeof BC; + + +//// [unionTypeEquivalence.js] +var __extends = this.__extends || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + __.prototype = b.prototype; + d.prototype = new __(); +}; +// A | B is equivalent to A if B is a subtype of A +var C = (function () { + function C() { + } + return C; +})(); +var D = (function (_super) { + __extends(D, _super); + function D() { + _super.apply(this, arguments); + } + return D; +})(C); +var x; +var x; +// A | B is equivalent to B | A. +var y; +var y; +// AB | C is equivalent to A | BC, where AB is A | B and BC is B | C. +var z; +var z; +var z; +var AB; +var BC; +var z1; +var z1; diff --git a/tests/baselines/reference/unionTypeEquivalence.types b/tests/baselines/reference/unionTypeEquivalence.types new file mode 100644 index 00000000000..53e95659120 --- /dev/null +++ b/tests/baselines/reference/unionTypeEquivalence.types @@ -0,0 +1,49 @@ +=== tests/cases/conformance/types/union/unionTypeEquivalence.ts === +// A | B is equivalent to A if B is a subtype of A +class C { } +>C : C + +class D extends C { } +>D : D +>C : C + +var x: C; +>x : C +>C : C + +var x : C | D; +>x : C +>C : C +>D : D + +// A | B is equivalent to B | A. +var y: string | number; +>y : string | number + +var y : number | string; +>y : string | number + +// AB | C is equivalent to A | BC, where AB is A | B and BC is B | C. +var z : string | number | boolean; +>z : string | number | boolean + +var z : (string | number) | boolean; +>z : string | number | boolean + +var z : string | (number | boolean); +>z : string | number | boolean + +var AB : string | number; +>AB : string | number + +var BC : number | boolean; +>BC : number | boolean + +var z1: typeof AB | boolean; +>z1 : string | number | boolean +>AB : string | number + +var z1: string | typeof BC; +>z1 : string | number | boolean +>BC : number | boolean + diff --git a/tests/cases/conformance/types/union/unionTypeEquivalence.ts b/tests/cases/conformance/types/union/unionTypeEquivalence.ts new file mode 100644 index 00000000000..0905fde17f8 --- /dev/null +++ b/tests/cases/conformance/types/union/unionTypeEquivalence.ts @@ -0,0 +1,18 @@ +// A | B is equivalent to A if B is a subtype of A +class C { } +class D extends C { } +var x: C; +var x : C | D; + +// A | B is equivalent to B | A. +var y: string | number; +var y : number | string; + +// AB | C is equivalent to A | BC, where AB is A | B and BC is B | C. +var z : string | number | boolean; +var z : (string | number) | boolean; +var z : string | (number | boolean); +var AB : string | number; +var BC : number | boolean; +var z1: typeof AB | boolean; +var z1: string | typeof BC; From a1535533e7da2e8688c5f3f4b6cbc979633e5ecf Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 3 Nov 2014 09:30:49 -0800 Subject: [PATCH 03/15] Tests for source (S) of subtype is union type (U) A union type U is a subtype of a type T if each type in U is a subtype of T --- ...IfEveryConstituentTypeIsSubtype.errors.txt | 239 ++++++++++++++++++ ...nSubtypeIfEveryConstituentTypeIsSubtype.js | 180 +++++++++++++ ...nSubtypeIfEveryConstituentTypeIsSubtype.ts | 143 +++++++++++ 3 files changed, 562 insertions(+) create mode 100644 tests/baselines/reference/unionSubtypeIfEveryConstituentTypeIsSubtype.errors.txt create mode 100644 tests/baselines/reference/unionSubtypeIfEveryConstituentTypeIsSubtype.js create mode 100644 tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts diff --git a/tests/baselines/reference/unionSubtypeIfEveryConstituentTypeIsSubtype.errors.txt b/tests/baselines/reference/unionSubtypeIfEveryConstituentTypeIsSubtype.errors.txt new file mode 100644 index 00000000000..013b5d9a990 --- /dev/null +++ b/tests/baselines/reference/unionSubtypeIfEveryConstituentTypeIsSubtype.errors.txt @@ -0,0 +1,239 @@ +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(15,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(21,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'string'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(22,5): error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'string'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(28,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'boolean'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(29,5): error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'boolean'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(35,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'Date'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(36,5): error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'Date'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(42,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'RegExp'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(43,5): error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'RegExp'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(49,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type '{ bar: number; }'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(50,5): error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type '{ bar: number; }'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(56,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'number[]'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(57,5): error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'number[]'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(63,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'I8'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(64,5): error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'I8'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(70,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'A'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(71,5): error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'A'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(77,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'A2'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(78,5): error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'A2'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(84,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type '(x: any) => number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(85,5): error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type '(x: any) => number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(91,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type '(x: T) => T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(92,5): error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type '(x: T) => T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(99,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'E2'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(100,5): error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'E2'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(110,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'typeof f'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(111,5): error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'typeof f'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(121,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'typeof c'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(122,5): error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'typeof c'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(128,5): error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'T'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts(129,5): error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'T'. + + +==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts (31 errors) ==== + enum e { + e1, + e2 + } + + // A union type U is a subtype of a type T if each type in U is a subtype of T + interface I { + [x: string]: any; + foo: string | number; // ok + foo2: e | number; // ok + } + interface I2 { + [x: string]: number; + // S is union type and each constituent type of S is a subtype of T + foo: string | number; // error string is not subtype of number + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'number'. + foo2: e | number; // ok e and number both subtype of number + } + + interface I3 { + [x: string]: string; + foo: string | number; // error numer is not subtype of string + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'string'. + foo2: e | number; // error e and number both not subtype of string + ~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'string'. + } + + // error cases + interface I4 { + [x: string]: boolean; + foo: string | number; + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'boolean'. + foo2: e | number; + ~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'boolean'. + } + + + interface I5 { + [x: string]: Date; + foo: string | number; + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'Date'. + foo2: e | number; + ~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'Date'. + } + + + interface I6 { + [x: string]: RegExp; + foo: string | number; + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'RegExp'. + foo2: e | number; + ~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'RegExp'. + } + + + interface I7 { + [x: string]: { bar: number }; + foo: string | number; + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type '{ bar: number; }'. + foo2: e | number; + ~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type '{ bar: number; }'. + } + + + interface I8 { + [x: string]: number[]; + foo: string | number; + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'number[]'. + foo2: e | number; + ~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'number[]'. + } + + + interface I9 { + [x: string]: I8; + foo: string | number; + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'I8'. + foo2: e | number; + ~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'I8'. + } + + class A { foo: number; } + interface I10 { + [x: string]: A; + foo: string | number; + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'A'. + foo2: e | number; + ~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'A'. + } + + class A2 { foo: T; } + interface I11 { + [x: string]: A2; + foo: string | number; + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'A2'. + foo2: e | number; + ~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'A2'. + } + + + interface I12 { + [x: string]: (x) => number; + foo: string | number; + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type '(x: any) => number'. + foo2: e | number; + ~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type '(x: any) => number'. + } + + + interface I13 { + [x: string]: (x: T) => T; + foo: string | number; + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type '(x: T) => T'. + foo2: e | number; + ~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type '(x: T) => T'. + } + + + enum E2 { A } + interface I14 { + [x: string]: E2; + foo: string | number; + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'E2'. + foo2: e | number; + ~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'E2'. + } + + + function f() { } + module f { + export var bar = 1; + } + interface I15 { + [x: string]: typeof f; + foo: string | number; + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'typeof f'. + foo2: e | number; + ~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'typeof f'. + } + + + class c { baz: string } + module c { + export var bar = 1; + } + interface I16 { + [x: string]: typeof c; + foo: string | number; + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'typeof c'. + foo2: e | number; + ~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'typeof c'. + } + + + interface I17 { + [x: string]: T; + foo: string | number; + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo' of type 'string | number' is not assignable to string index type 'T'. + foo2: e | number; + ~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo2' of type 'number | e' is not assignable to string index type 'T'. + } + + interface I19 { + [x: string]: Object; + foo: string | number; + foo2: e | number; + } + + + interface I20 { + [x: string]: {}; + foo: string | number; + foo2: e | number; + } \ No newline at end of file diff --git a/tests/baselines/reference/unionSubtypeIfEveryConstituentTypeIsSubtype.js b/tests/baselines/reference/unionSubtypeIfEveryConstituentTypeIsSubtype.js new file mode 100644 index 00000000000..0c9ffeb5653 --- /dev/null +++ b/tests/baselines/reference/unionSubtypeIfEveryConstituentTypeIsSubtype.js @@ -0,0 +1,180 @@ +//// [unionSubtypeIfEveryConstituentTypeIsSubtype.ts] +enum e { + e1, + e2 +} + +// A union type U is a subtype of a type T if each type in U is a subtype of T +interface I { + [x: string]: any; + foo: string | number; // ok + foo2: e | number; // ok +} +interface I2 { + [x: string]: number; + // S is union type and each constituent type of S is a subtype of T + foo: string | number; // error string is not subtype of number + foo2: e | number; // ok e and number both subtype of number +} + +interface I3 { + [x: string]: string; + foo: string | number; // error numer is not subtype of string + foo2: e | number; // error e and number both not subtype of string +} + +// error cases +interface I4 { + [x: string]: boolean; + foo: string | number; + foo2: e | number; +} + + +interface I5 { + [x: string]: Date; + foo: string | number; + foo2: e | number; +} + + +interface I6 { + [x: string]: RegExp; + foo: string | number; + foo2: e | number; +} + + +interface I7 { + [x: string]: { bar: number }; + foo: string | number; + foo2: e | number; +} + + +interface I8 { + [x: string]: number[]; + foo: string | number; + foo2: e | number; +} + + +interface I9 { + [x: string]: I8; + foo: string | number; + foo2: e | number; +} + +class A { foo: number; } +interface I10 { + [x: string]: A; + foo: string | number; + foo2: e | number; +} + +class A2 { foo: T; } +interface I11 { + [x: string]: A2; + foo: string | number; + foo2: e | number; +} + + +interface I12 { + [x: string]: (x) => number; + foo: string | number; + foo2: e | number; +} + + +interface I13 { + [x: string]: (x: T) => T; + foo: string | number; + foo2: e | number; +} + + +enum E2 { A } +interface I14 { + [x: string]: E2; + foo: string | number; + foo2: e | number; +} + + +function f() { } +module f { + export var bar = 1; +} +interface I15 { + [x: string]: typeof f; + foo: string | number; + foo2: e | number; +} + + +class c { baz: string } +module c { + export var bar = 1; +} +interface I16 { + [x: string]: typeof c; + foo: string | number; + foo2: e | number; +} + + +interface I17 { + [x: string]: T; + foo: string | number; + foo2: e | number; +} + +interface I19 { + [x: string]: Object; + foo: string | number; + foo2: e | number; +} + + +interface I20 { + [x: string]: {}; + foo: string | number; + foo2: e | number; +} + +//// [unionSubtypeIfEveryConstituentTypeIsSubtype.js] +var e; +(function (e) { + e[e["e1"] = 0] = "e1"; + e[e["e2"] = 1] = "e2"; +})(e || (e = {})); +var A = (function () { + function A() { + } + return A; +})(); +var A2 = (function () { + function A2() { + } + return A2; +})(); +var E2; +(function (E2) { + E2[E2["A"] = 0] = "A"; +})(E2 || (E2 = {})); +function f() { +} +var f; +(function (f) { + f.bar = 1; +})(f || (f = {})); +var c = (function () { + function c() { + } + return c; +})(); +var c; +(function (c) { + c.bar = 1; +})(c || (c = {})); diff --git a/tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts b/tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts new file mode 100644 index 00000000000..7caa26a2959 --- /dev/null +++ b/tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/unionSubtypeIfEveryConstituentTypeIsSubtype.ts @@ -0,0 +1,143 @@ +enum e { + e1, + e2 +} + +// A union type U is a subtype of a type T if each type in U is a subtype of T +interface I { + [x: string]: any; + foo: string | number; // ok + foo2: e | number; // ok +} +interface I2 { + [x: string]: number; + // S is union type and each constituent type of S is a subtype of T + foo: string | number; // error string is not subtype of number + foo2: e | number; // ok e and number both subtype of number +} + +interface I3 { + [x: string]: string; + foo: string | number; // error numer is not subtype of string + foo2: e | number; // error e and number both not subtype of string +} + +// error cases +interface I4 { + [x: string]: boolean; + foo: string | number; + foo2: e | number; +} + + +interface I5 { + [x: string]: Date; + foo: string | number; + foo2: e | number; +} + + +interface I6 { + [x: string]: RegExp; + foo: string | number; + foo2: e | number; +} + + +interface I7 { + [x: string]: { bar: number }; + foo: string | number; + foo2: e | number; +} + + +interface I8 { + [x: string]: number[]; + foo: string | number; + foo2: e | number; +} + + +interface I9 { + [x: string]: I8; + foo: string | number; + foo2: e | number; +} + +class A { foo: number; } +interface I10 { + [x: string]: A; + foo: string | number; + foo2: e | number; +} + +class A2 { foo: T; } +interface I11 { + [x: string]: A2; + foo: string | number; + foo2: e | number; +} + + +interface I12 { + [x: string]: (x) => number; + foo: string | number; + foo2: e | number; +} + + +interface I13 { + [x: string]: (x: T) => T; + foo: string | number; + foo2: e | number; +} + + +enum E2 { A } +interface I14 { + [x: string]: E2; + foo: string | number; + foo2: e | number; +} + + +function f() { } +module f { + export var bar = 1; +} +interface I15 { + [x: string]: typeof f; + foo: string | number; + foo2: e | number; +} + + +class c { baz: string } +module c { + export var bar = 1; +} +interface I16 { + [x: string]: typeof c; + foo: string | number; + foo2: e | number; +} + + +interface I17 { + [x: string]: T; + foo: string | number; + foo2: e | number; +} + +interface I19 { + [x: string]: Object; + foo: string | number; + foo2: e | number; +} + + +interface I20 { + [x: string]: {}; + foo: string | number; + foo2: e | number; +} \ No newline at end of file From 703cd5d4cfed329688984c1d26ae6fc844b6cdd3 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 3 Nov 2014 09:46:32 -0800 Subject: [PATCH 04/15] Tests for checking if type S is subtype of union type T is a union type and S is a subtype of at least one constituent type of T --- .../reference/subtypesOfUnion.errors.txt | 142 ++++++++++++++++++ tests/baselines/reference/subtypesOfUnion.js | 85 +++++++++++ .../subtypesAndSuperTypes/subtypesOfUnion.ts | 52 +++++++ 3 files changed, 279 insertions(+) create mode 100644 tests/baselines/reference/subtypesOfUnion.errors.txt create mode 100644 tests/baselines/reference/subtypesOfUnion.js create mode 100644 tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts diff --git a/tests/baselines/reference/subtypesOfUnion.errors.txt b/tests/baselines/reference/subtypesOfUnion.errors.txt new file mode 100644 index 00000000000..fade5377814 --- /dev/null +++ b/tests/baselines/reference/subtypesOfUnion.errors.txt @@ -0,0 +1,142 @@ +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(16,5): error TS2411: Property 'foo4' of type 'boolean' is not assignable to string index type 'string | number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(18,5): error TS2411: Property 'foo6' of type 'Date' is not assignable to string index type 'string | number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(19,5): error TS2411: Property 'foo7' of type 'RegExp' is not assignable to string index type 'string | number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(20,5): error TS2411: Property 'foo8' of type '{ bar: number; }' is not assignable to string index type 'string | number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(21,5): error TS2411: Property 'foo9' of type 'I8' is not assignable to string index type 'string | number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(22,5): error TS2411: Property 'foo10' of type 'A' is not assignable to string index type 'string | number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(23,5): error TS2411: Property 'foo11' of type 'A2' is not assignable to string index type 'string | number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(24,5): error TS2411: Property 'foo12' of type '(x: any) => number' is not assignable to string index type 'string | number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(25,5): error TS2411: Property 'foo13' of type '(x: T) => T' is not assignable to string index type 'string | number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(26,5): error TS2411: Property 'foo14' of type 'typeof f' is not assignable to string index type 'string | number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(27,5): error TS2411: Property 'foo15' of type 'typeof c' is not assignable to string index type 'string | number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(28,5): error TS2411: Property 'foo16' of type 'T' is not assignable to string index type 'string | number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(29,5): error TS2411: Property 'foo17' of type 'Object' is not assignable to string index type 'string | number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(30,5): error TS2411: Property 'foo18' of type '{}' is not assignable to string index type 'string | number'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(35,5): error TS2411: Property 'foo2' of type 'string' is not assignable to string index type 'number | E'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(37,5): error TS2411: Property 'foo4' of type 'boolean' is not assignable to string index type 'number | E'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(39,5): error TS2411: Property 'foo6' of type 'Date' is not assignable to string index type 'number | E'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(40,5): error TS2411: Property 'foo7' of type 'RegExp' is not assignable to string index type 'number | E'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(41,5): error TS2411: Property 'foo8' of type '{ bar: number; }' is not assignable to string index type 'number | E'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(42,5): error TS2411: Property 'foo9' of type 'I8' is not assignable to string index type 'number | E'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(43,5): error TS2411: Property 'foo10' of type 'A' is not assignable to string index type 'number | E'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(44,5): error TS2411: Property 'foo11' of type 'A2' is not assignable to string index type 'number | E'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(45,5): error TS2411: Property 'foo12' of type '(x: any) => number' is not assignable to string index type 'number | E'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(46,5): error TS2411: Property 'foo13' of type '(x: T) => T' is not assignable to string index type 'number | E'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(47,5): error TS2411: Property 'foo14' of type 'typeof f' is not assignable to string index type 'number | E'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(48,5): error TS2411: Property 'foo15' of type 'typeof c' is not assignable to string index type 'number | E'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(49,5): error TS2411: Property 'foo16' of type 'T' is not assignable to string index type 'number | E'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(50,5): error TS2411: Property 'foo17' of type 'Object' is not assignable to string index type 'number | E'. +tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts(51,5): error TS2411: Property 'foo18' of type '{}' is not assignable to string index type 'number | E'. + + +==== tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts (29 errors) ==== + enum E { e1, e2 } + interface I8 { [x: string]: number[]; } + class A { foo: number; } + class A2 { foo: T; } + function f() { } + module f { export var bar = 1; } + class c { baz: string } + module c { export var bar = 1; } + + // A type T is a subtype of a union type U if T is a subtype of any type in U. + interface I1 { + [x: string]: string | number; + foo: any; // ok + foo2: string; // ok + foo3: number; // ok + foo4: boolean; // error + ~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo4' of type 'boolean' is not assignable to string index type 'string | number'. + foo5: E; // ok - subtype of number + foo6: Date; // error + ~~~~~~~~~~~ +!!! error TS2411: Property 'foo6' of type 'Date' is not assignable to string index type 'string | number'. + foo7: RegExp; // error + ~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo7' of type 'RegExp' is not assignable to string index type 'string | number'. + foo8: { bar: number }; // error + ~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo8' of type '{ bar: number; }' is not assignable to string index type 'string | number'. + foo9: I8; // error + ~~~~~~~~~ +!!! error TS2411: Property 'foo9' of type 'I8' is not assignable to string index type 'string | number'. + foo10: A; // error + ~~~~~~~~~ +!!! error TS2411: Property 'foo10' of type 'A' is not assignable to string index type 'string | number'. + foo11: A2; // error + ~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo11' of type 'A2' is not assignable to string index type 'string | number'. + foo12: (x) => number; //error + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo12' of type '(x: any) => number' is not assignable to string index type 'string | number'. + foo13: (x: T) => T; // error + ~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo13' of type '(x: T) => T' is not assignable to string index type 'string | number'. + foo14: typeof f; // error + ~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo14' of type 'typeof f' is not assignable to string index type 'string | number'. + foo15: typeof c; // error + ~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo15' of type 'typeof c' is not assignable to string index type 'string | number'. + foo16: T; // error + ~~~~~~~~~ +!!! error TS2411: Property 'foo16' of type 'T' is not assignable to string index type 'string | number'. + foo17: Object; // error + ~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo17' of type 'Object' is not assignable to string index type 'string | number'. + foo18: {}; // error + ~~~~~~~~~~ +!!! error TS2411: Property 'foo18' of type '{}' is not assignable to string index type 'string | number'. + } + interface I2 { + [x: string]: E | number; + foo: any; // ok + foo2: string; // error + ~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo2' of type 'string' is not assignable to string index type 'number | E'. + foo3: number; // ok + foo4: boolean; // error + ~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo4' of type 'boolean' is not assignable to string index type 'number | E'. + foo5: E; // ok + foo6: Date; // error + ~~~~~~~~~~~ +!!! error TS2411: Property 'foo6' of type 'Date' is not assignable to string index type 'number | E'. + foo7: RegExp; // error + ~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo7' of type 'RegExp' is not assignable to string index type 'number | E'. + foo8: { bar: number }; // error + ~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo8' of type '{ bar: number; }' is not assignable to string index type 'number | E'. + foo9: I8; // error + ~~~~~~~~~ +!!! error TS2411: Property 'foo9' of type 'I8' is not assignable to string index type 'number | E'. + foo10: A; // error + ~~~~~~~~~ +!!! error TS2411: Property 'foo10' of type 'A' is not assignable to string index type 'number | E'. + foo11: A2; // error + ~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo11' of type 'A2' is not assignable to string index type 'number | E'. + foo12: (x) => number; //error + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo12' of type '(x: any) => number' is not assignable to string index type 'number | E'. + foo13: (x: T) => T; // error + ~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo13' of type '(x: T) => T' is not assignable to string index type 'number | E'. + foo14: typeof f; // error + ~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo14' of type 'typeof f' is not assignable to string index type 'number | E'. + foo15: typeof c; // error + ~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo15' of type 'typeof c' is not assignable to string index type 'number | E'. + foo16: T; // error + ~~~~~~~~~ +!!! error TS2411: Property 'foo16' of type 'T' is not assignable to string index type 'number | E'. + foo17: Object; // error + ~~~~~~~~~~~~~~ +!!! error TS2411: Property 'foo17' of type 'Object' is not assignable to string index type 'number | E'. + foo18: {}; // error + ~~~~~~~~~~ +!!! error TS2411: Property 'foo18' of type '{}' is not assignable to string index type 'number | E'. + } \ No newline at end of file diff --git a/tests/baselines/reference/subtypesOfUnion.js b/tests/baselines/reference/subtypesOfUnion.js new file mode 100644 index 00000000000..a18ebb944b9 --- /dev/null +++ b/tests/baselines/reference/subtypesOfUnion.js @@ -0,0 +1,85 @@ +//// [subtypesOfUnion.ts] +enum E { e1, e2 } +interface I8 { [x: string]: number[]; } +class A { foo: number; } +class A2 { foo: T; } +function f() { } +module f { export var bar = 1; } +class c { baz: string } +module c { export var bar = 1; } + +// A type T is a subtype of a union type U if T is a subtype of any type in U. +interface I1 { + [x: string]: string | number; + foo: any; // ok + foo2: string; // ok + foo3: number; // ok + foo4: boolean; // error + foo5: E; // ok - subtype of number + foo6: Date; // error + foo7: RegExp; // error + foo8: { bar: number }; // error + foo9: I8; // error + foo10: A; // error + foo11: A2; // error + foo12: (x) => number; //error + foo13: (x: T) => T; // error + foo14: typeof f; // error + foo15: typeof c; // error + foo16: T; // error + foo17: Object; // error + foo18: {}; // error +} +interface I2 { + [x: string]: E | number; + foo: any; // ok + foo2: string; // error + foo3: number; // ok + foo4: boolean; // error + foo5: E; // ok + foo6: Date; // error + foo7: RegExp; // error + foo8: { bar: number }; // error + foo9: I8; // error + foo10: A; // error + foo11: A2; // error + foo12: (x) => number; //error + foo13: (x: T) => T; // error + foo14: typeof f; // error + foo15: typeof c; // error + foo16: T; // error + foo17: Object; // error + foo18: {}; // error +} + +//// [subtypesOfUnion.js] +var E; +(function (E) { + E[E["e1"] = 0] = "e1"; + E[E["e2"] = 1] = "e2"; +})(E || (E = {})); +var A = (function () { + function A() { + } + return A; +})(); +var A2 = (function () { + function A2() { + } + return A2; +})(); +function f() { +} +var f; +(function (f) { + f.bar = 1; +})(f || (f = {})); +var c = (function () { + function c() { + } + return c; +})(); +var c; +(function (c) { + c.bar = 1; +})(c || (c = {})); diff --git a/tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts b/tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts new file mode 100644 index 00000000000..c20bafeeabf --- /dev/null +++ b/tests/cases/conformance/types/typeRelationships/subtypesAndSuperTypes/subtypesOfUnion.ts @@ -0,0 +1,52 @@ +enum E { e1, e2 } +interface I8 { [x: string]: number[]; } +class A { foo: number; } +class A2 { foo: T; } +function f() { } +module f { export var bar = 1; } +class c { baz: string } +module c { export var bar = 1; } + +// A type T is a subtype of a union type U if T is a subtype of any type in U. +interface I1 { + [x: string]: string | number; + foo: any; // ok + foo2: string; // ok + foo3: number; // ok + foo4: boolean; // error + foo5: E; // ok - subtype of number + foo6: Date; // error + foo7: RegExp; // error + foo8: { bar: number }; // error + foo9: I8; // error + foo10: A; // error + foo11: A2; // error + foo12: (x) => number; //error + foo13: (x: T) => T; // error + foo14: typeof f; // error + foo15: typeof c; // error + foo16: T; // error + foo17: Object; // error + foo18: {}; // error +} +interface I2 { + [x: string]: E | number; + foo: any; // ok + foo2: string; // error + foo3: number; // ok + foo4: boolean; // error + foo5: E; // ok + foo6: Date; // error + foo7: RegExp; // error + foo8: { bar: number }; // error + foo9: I8; // error + foo10: A; // error + foo11: A2; // error + foo12: (x) => number; //error + foo13: (x: T) => T; // error + foo14: typeof f; // error + foo15: typeof c; // error + foo16: T; // error + foo17: Object; // error + foo18: {}; // error +} \ No newline at end of file From 1f3653b32e98e1fe5861c3c3aa16881aaa60a16e Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 3 Nov 2014 10:08:40 -0800 Subject: [PATCH 05/15] =?UTF-8?q?Tests=20for=20assignment=20compatibility?= =?UTF-8?q?=20of=20union=20types=20=E2=80=A2=09A=20union=20type=20U=20is?= =?UTF-8?q?=20assignable=20to=20a=20type=20T=20if=20each=20type=20in=20U?= =?UTF-8?q?=20is=20assignable=20to=20T.=20=E2=80=A2=09A=20type=20T=20is=20?= =?UTF-8?q?assignable=20to=20a=20union=20type=20U=20if=20T=20is=20assignab?= =?UTF-8?q?le=20to=20any=20type=20in=20U.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../unionTypesAssignability.errors.txt | 154 ++++++++++++++++ .../reference/unionTypesAssignability.js | 165 ++++++++++++++++++ .../unionTypesAssignability.ts | 71 ++++++++ 3 files changed, 390 insertions(+) create mode 100644 tests/baselines/reference/unionTypesAssignability.errors.txt create mode 100644 tests/baselines/reference/unionTypesAssignability.js create mode 100644 tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts diff --git a/tests/baselines/reference/unionTypesAssignability.errors.txt b/tests/baselines/reference/unionTypesAssignability.errors.txt new file mode 100644 index 00000000000..b32f71a38c1 --- /dev/null +++ b/tests/baselines/reference/unionTypesAssignability.errors.txt @@ -0,0 +1,154 @@ +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts(18,1): error TS2323: Type 'E' is not assignable to type 'D'. + Property 'foo1' is missing in type 'E'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts(19,1): error TS2323: Type 'D | E' is not assignable to type 'D'. + Type 'E' is not assignable to type 'D'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts(20,1): error TS2323: Type 'D' is not assignable to type 'E'. + Property 'foo2' is missing in type 'D'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts(22,1): error TS2323: Type 'D | E' is not assignable to type 'E'. + Type 'D' is not assignable to type 'E'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts(24,1): error TS2323: Type 'string' is not assignable to type 'number'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts(25,1): error TS2323: Type 'string | number' is not assignable to type 'number'. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts(26,1): error TS2323: Type 'number' is not assignable to type 'string'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts(28,1): error TS2323: Type 'string | number' is not assignable to type 'string'. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts(31,1): error TS2323: Type 'C' is not assignable to type 'D'. + Property 'foo1' is missing in type 'C'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts(32,1): error TS2323: Type 'C' is not assignable to type 'E'. + Property 'foo2' is missing in type 'C'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts(33,1): error TS2323: Type 'C' is not assignable to type 'D | E'. + Type 'C' is not assignable to type 'E'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts(35,1): error TS2323: Type 'D' is not assignable to type 'E'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts(37,1): error TS2323: Type 'E' is not assignable to type 'D'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts(41,1): error TS2323: Type 'number' is not assignable to type 'string'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts(43,1): error TS2323: Type 'string' is not assignable to type 'number'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts(64,5): error TS2323: Type 'U' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts(65,5): error TS2323: Type 'T' is not assignable to type 'U'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts(69,5): error TS2323: Type 'T | U' is not assignable to type 'T'. + Type 'U' is not assignable to type 'T'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts(70,5): error TS2323: Type 'T | U' is not assignable to type 'U'. + Type 'T' is not assignable to type 'U'. + + +==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts (19 errors) ==== + var unionNumberString: number | string; + class C { } + class D extends C { foo1() { } } + class E extends C { foo2() { } } + var unionDE: D | E; + + var num: number; + var str: string; + var c: C; + var d: D; + var e: E; + + // A union type U is assignable to a type T if each type in U is assignable to T + c = d; + c = e; + c = unionDE; // ok + d = d; + d = e; + ~ +!!! error TS2323: Type 'E' is not assignable to type 'D'. +!!! error TS2323: Property 'foo1' is missing in type 'E'. + d = unionDE; // error e is not assignable to d + ~ +!!! error TS2323: Type 'D | E' is not assignable to type 'D'. +!!! error TS2323: Type 'E' is not assignable to type 'D'. + e = d; + ~ +!!! error TS2323: Type 'D' is not assignable to type 'E'. +!!! error TS2323: Property 'foo2' is missing in type 'D'. + e = e; + e = unionDE; // error d is not assignable to e + ~ +!!! error TS2323: Type 'D | E' is not assignable to type 'E'. +!!! error TS2323: Type 'D' is not assignable to type 'E'. + num = num; + num = str; + ~~~ +!!! error TS2323: Type 'string' is not assignable to type 'number'. + num = unionNumberString; // error string is not assignable to number + ~~~ +!!! error TS2323: Type 'string | number' is not assignable to type 'number'. +!!! error TS2323: Type 'string' is not assignable to type 'number'. + str = num; + ~~~ +!!! error TS2323: Type 'number' is not assignable to type 'string'. + str = str; + str = unionNumberString; // error since number is not assignable to string + ~~~ +!!! error TS2323: Type 'string | number' is not assignable to type 'string'. +!!! error TS2323: Type 'number' is not assignable to type 'string'. + + // A type T is assignable to a union type U if T is assignable to any type in U + d = c; + ~ +!!! error TS2323: Type 'C' is not assignable to type 'D'. +!!! error TS2323: Property 'foo1' is missing in type 'C'. + e = c; + ~ +!!! error TS2323: Type 'C' is not assignable to type 'E'. +!!! error TS2323: Property 'foo2' is missing in type 'C'. + unionDE = c; // error since C is not assinable to either D or E + ~~~~~~~ +!!! error TS2323: Type 'C' is not assignable to type 'D | E'. +!!! error TS2323: Type 'C' is not assignable to type 'E'. + d = d; + e = d; + ~ +!!! error TS2323: Type 'D' is not assignable to type 'E'. + unionDE = d; // ok + d = e; + ~ +!!! error TS2323: Type 'E' is not assignable to type 'D'. + e = e; + unionDE = e; // ok + num = num; + str = num; + ~~~ +!!! error TS2323: Type 'number' is not assignable to type 'string'. + unionNumberString = num; // ok + num = str; + ~~~ +!!! error TS2323: Type 'string' is not assignable to type 'number'. + str = str; + unionNumberString = str; // ok + + // Any + var anyVar: any; + anyVar = unionDE; + anyVar = unionNumberString; + unionDE = anyVar; + unionNumberString = anyVar; + + // null + unionDE = null; + unionNumberString = null; + + // undefined + unionDE = undefined; + unionNumberString = undefined; + + // type parameters + function foo(t: T, u: U) { + t = u; // error + ~ +!!! error TS2323: Type 'U' is not assignable to type 'T'. + u = t; // error + ~ +!!! error TS2323: Type 'T' is not assignable to type 'U'. + var x : T | U; + x = t; // ok + x = u; // ok + t = x; // error U not assignable to T + ~ +!!! error TS2323: Type 'T | U' is not assignable to type 'T'. +!!! error TS2323: Type 'U' is not assignable to type 'T'. + u = x; // error T not assignable to U + ~ +!!! error TS2323: Type 'T | U' is not assignable to type 'U'. +!!! error TS2323: Type 'T' is not assignable to type 'U'. + } + \ No newline at end of file diff --git a/tests/baselines/reference/unionTypesAssignability.js b/tests/baselines/reference/unionTypesAssignability.js new file mode 100644 index 00000000000..a67f23bb09f --- /dev/null +++ b/tests/baselines/reference/unionTypesAssignability.js @@ -0,0 +1,165 @@ +//// [unionTypesAssignability.ts] +var unionNumberString: number | string; +class C { } +class D extends C { foo1() { } } +class E extends C { foo2() { } } +var unionDE: D | E; + +var num: number; +var str: string; +var c: C; +var d: D; +var e: E; + +// A union type U is assignable to a type T if each type in U is assignable to T +c = d; +c = e; +c = unionDE; // ok +d = d; +d = e; +d = unionDE; // error e is not assignable to d +e = d; +e = e; +e = unionDE; // error d is not assignable to e +num = num; +num = str; +num = unionNumberString; // error string is not assignable to number +str = num; +str = str; +str = unionNumberString; // error since number is not assignable to string + +// A type T is assignable to a union type U if T is assignable to any type in U +d = c; +e = c; +unionDE = c; // error since C is not assinable to either D or E +d = d; +e = d; +unionDE = d; // ok +d = e; +e = e; +unionDE = e; // ok +num = num; +str = num; +unionNumberString = num; // ok +num = str; +str = str; +unionNumberString = str; // ok + +// Any +var anyVar: any; +anyVar = unionDE; +anyVar = unionNumberString; +unionDE = anyVar; +unionNumberString = anyVar; + +// null +unionDE = null; +unionNumberString = null; + +// undefined +unionDE = undefined; +unionNumberString = undefined; + +// type parameters +function foo(t: T, u: U) { + t = u; // error + u = t; // error + var x : T | U; + x = t; // ok + x = u; // ok + t = x; // error U not assignable to T + u = x; // error T not assignable to U +} + + +//// [unionTypesAssignability.js] +var __extends = this.__extends || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + __.prototype = b.prototype; + d.prototype = new __(); +}; +var unionNumberString; +var C = (function () { + function C() { + } + return C; +})(); +var D = (function (_super) { + __extends(D, _super); + function D() { + _super.apply(this, arguments); + } + D.prototype.foo1 = function () { + }; + return D; +})(C); +var E = (function (_super) { + __extends(E, _super); + function E() { + _super.apply(this, arguments); + } + E.prototype.foo2 = function () { + }; + return E; +})(C); +var unionDE; +var num; +var str; +var c; +var d; +var e; +// A union type U is assignable to a type T if each type in U is assignable to T +c = d; +c = e; +c = unionDE; // ok +d = d; +d = e; +d = unionDE; // error e is not assignable to d +e = d; +e = e; +e = unionDE; // error d is not assignable to e +num = num; +num = str; +num = unionNumberString; // error string is not assignable to number +str = num; +str = str; +str = unionNumberString; // error since number is not assignable to string +// A type T is assignable to a union type U if T is assignable to any type in U +d = c; +e = c; +unionDE = c; // error since C is not assinable to either D or E +d = d; +e = d; +unionDE = d; // ok +d = e; +e = e; +unionDE = e; // ok +num = num; +str = num; +unionNumberString = num; // ok +num = str; +str = str; +unionNumberString = str; // ok +// Any +var anyVar; +anyVar = unionDE; +anyVar = unionNumberString; +unionDE = anyVar; +unionNumberString = anyVar; +// null +unionDE = null; +unionNumberString = null; +// undefined +unionDE = undefined; +unionNumberString = undefined; +// type parameters +function foo(t, u) { + t = u; // error + u = t; // error + var x; + x = t; // ok + x = u; // ok + t = x; // error U not assignable to T + u = x; // error T not assignable to U +} diff --git a/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts b/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts new file mode 100644 index 00000000000..9ceee8845a5 --- /dev/null +++ b/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/unionTypesAssignability.ts @@ -0,0 +1,71 @@ +var unionNumberString: number | string; +class C { } +class D extends C { foo1() { } } +class E extends C { foo2() { } } +var unionDE: D | E; + +var num: number; +var str: string; +var c: C; +var d: D; +var e: E; + +// A union type U is assignable to a type T if each type in U is assignable to T +c = d; +c = e; +c = unionDE; // ok +d = d; +d = e; +d = unionDE; // error e is not assignable to d +e = d; +e = e; +e = unionDE; // error d is not assignable to e +num = num; +num = str; +num = unionNumberString; // error string is not assignable to number +str = num; +str = str; +str = unionNumberString; // error since number is not assignable to string + +// A type T is assignable to a union type U if T is assignable to any type in U +d = c; +e = c; +unionDE = c; // error since C is not assinable to either D or E +d = d; +e = d; +unionDE = d; // ok +d = e; +e = e; +unionDE = e; // ok +num = num; +str = num; +unionNumberString = num; // ok +num = str; +str = str; +unionNumberString = str; // ok + +// Any +var anyVar: any; +anyVar = unionDE; +anyVar = unionNumberString; +unionDE = anyVar; +unionNumberString = anyVar; + +// null +unionDE = null; +unionNumberString = null; + +// undefined +unionDE = undefined; +unionNumberString = undefined; + +// type parameters +function foo(t: T, u: U) { + t = u; // error + u = t; // error + var x : T | U; + x = t; // ok + x = u; // ok + t = x; // error U not assignable to T + u = x; // error T not assignable to U +} From 357bd87612ba2e1f5302562a922f943405ea70b3 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 3 Nov 2014 13:20:30 -0800 Subject: [PATCH 06/15] Tests for union members: If each type in U has a property P, U has a property P of a union type of the types of P from each type in U. --- .../reference/unionTypeEquivalence.js | 4 +- .../reference/unionTypeEquivalence.types | 3 +- .../reference/unionTypeMembers.errors.txt | 72 +++++++++++++++++ tests/baselines/reference/unionTypeMembers.js | 79 +++++++++++++++++++ .../types/union/unionTypeEquivalence.ts | 2 +- .../types/union/unionTypeMembers.ts | 54 +++++++++++++ 6 files changed, 211 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/unionTypeMembers.errors.txt create mode 100644 tests/baselines/reference/unionTypeMembers.js create mode 100644 tests/cases/conformance/types/union/unionTypeMembers.ts diff --git a/tests/baselines/reference/unionTypeEquivalence.js b/tests/baselines/reference/unionTypeEquivalence.js index 3698ecd2f92..f9fdf2e58d7 100644 --- a/tests/baselines/reference/unionTypeEquivalence.js +++ b/tests/baselines/reference/unionTypeEquivalence.js @@ -1,7 +1,7 @@ //// [unionTypeEquivalence.ts] // A | B is equivalent to A if B is a subtype of A class C { } -class D extends C { } +class D extends C { foo() { } } var x: C; var x : C | D; @@ -37,6 +37,8 @@ var D = (function (_super) { function D() { _super.apply(this, arguments); } + D.prototype.foo = function () { + }; return D; })(C); var x; diff --git a/tests/baselines/reference/unionTypeEquivalence.types b/tests/baselines/reference/unionTypeEquivalence.types index 53e95659120..c4990a58132 100644 --- a/tests/baselines/reference/unionTypeEquivalence.types +++ b/tests/baselines/reference/unionTypeEquivalence.types @@ -3,9 +3,10 @@ class C { } >C : C -class D extends C { } +class D extends C { foo() { } } >D : D >C : C +>foo : () => void var x: C; >x : C diff --git a/tests/baselines/reference/unionTypeMembers.errors.txt b/tests/baselines/reference/unionTypeMembers.errors.txt new file mode 100644 index 00000000000..21f1204ac6d --- /dev/null +++ b/tests/baselines/reference/unionTypeMembers.errors.txt @@ -0,0 +1,72 @@ +tests/cases/conformance/types/union/unionTypeMembers.ts(44,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/conformance/types/union/unionTypeMembers.ts(51,3): error TS2339: Property 'propertyOnlyInI1' does not exist on type 'I1 | I2'. +tests/cases/conformance/types/union/unionTypeMembers.ts(52,3): error TS2339: Property 'propertyOnlyInI2' does not exist on type 'I1 | I2'. +tests/cases/conformance/types/union/unionTypeMembers.ts(53,3): error TS2339: Property 'methodOnlyInI1' does not exist on type 'I1 | I2'. +tests/cases/conformance/types/union/unionTypeMembers.ts(54,3): error TS2339: Property 'methodOnlyInI2' does not exist on type 'I1 | I2'. + + +==== tests/cases/conformance/types/union/unionTypeMembers.ts (5 errors) ==== + interface I1 { + commonMethodType(a: string): string; + commonPropertyType: string; + + commonMethodDifferentParameterType(a: string): string; + commonMethodDifferentReturnType(a: string): string; + commonPropertyDifferenType: string; + + commonMethodWithTypeParameter(a: T): T; + commonMethodWithOwnTypeParameter(a: U): U; + + methodOnlyInI1(a: string): string; + propertyOnlyInI1: string; + } + + interface I2 { + commonMethodType(a: string): string; + commonPropertyType: string; + + commonMethodDifferentParameterType(a: number): number; + commonMethodDifferentReturnType(a: string): number; + commonPropertyDifferenType: number; + + commonMethodWithTypeParameter(a: T): T; + commonMethodWithOwnTypeParameter(a: U): U; + + methodOnlyInI2(a: string): string; + propertyOnlyInI2: string; + } + + // a union type U has those members that are present in every one of its constituent types, + // with types that are unions of the respective members in the constituent types + var x : I1 | I2; + var str: string; + var num: number; + var strOrNum: string | number; + + // If each type in U has a property P, U has a property P of a union type of the types of P from each type in U. + str = x.commonPropertyType; // string + str = x.commonMethodType(str); // (a: string) => string so result should be string + strOrNum = x.commonPropertyDifferenType; + strOrNum = x.commonMethodDifferentReturnType(str); // string | union + x.commonMethodDifferentParameterType; // No error - property exists + x.commonMethodDifferentParameterType(strOrNum); // error - no call signatures because the type of this property is ((a: string) => string) | (a: number) => number + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + // and the call signatures arent identical + num = x.commonMethodWithTypeParameter(num); + num = x.commonMethodWithOwnTypeParameter(num); + str = x.commonMethodWithOwnTypeParameter(str); + strOrNum = x.commonMethodWithOwnTypeParameter(strOrNum); + + x.propertyOnlyInI1; // error + ~~~~~~~~~~~~~~~~ +!!! error TS2339: Property 'propertyOnlyInI1' does not exist on type 'I1 | I2'. + x.propertyOnlyInI2; // error + ~~~~~~~~~~~~~~~~ +!!! error TS2339: Property 'propertyOnlyInI2' does not exist on type 'I1 | I2'. + x.methodOnlyInI1("hello"); // error + ~~~~~~~~~~~~~~ +!!! error TS2339: Property 'methodOnlyInI1' does not exist on type 'I1 | I2'. + x.methodOnlyInI2(10); // error + ~~~~~~~~~~~~~~ +!!! error TS2339: Property 'methodOnlyInI2' does not exist on type 'I1 | I2'. \ No newline at end of file diff --git a/tests/baselines/reference/unionTypeMembers.js b/tests/baselines/reference/unionTypeMembers.js new file mode 100644 index 00000000000..b03572246b4 --- /dev/null +++ b/tests/baselines/reference/unionTypeMembers.js @@ -0,0 +1,79 @@ +//// [unionTypeMembers.ts] +interface I1 { + commonMethodType(a: string): string; + commonPropertyType: string; + + commonMethodDifferentParameterType(a: string): string; + commonMethodDifferentReturnType(a: string): string; + commonPropertyDifferenType: string; + + commonMethodWithTypeParameter(a: T): T; + commonMethodWithOwnTypeParameter(a: U): U; + + methodOnlyInI1(a: string): string; + propertyOnlyInI1: string; +} + +interface I2 { + commonMethodType(a: string): string; + commonPropertyType: string; + + commonMethodDifferentParameterType(a: number): number; + commonMethodDifferentReturnType(a: string): number; + commonPropertyDifferenType: number; + + commonMethodWithTypeParameter(a: T): T; + commonMethodWithOwnTypeParameter(a: U): U; + + methodOnlyInI2(a: string): string; + propertyOnlyInI2: string; +} + +// a union type U has those members that are present in every one of its constituent types, +// with types that are unions of the respective members in the constituent types +var x : I1 | I2; +var str: string; +var num: number; +var strOrNum: string | number; + +// If each type in U has a property P, U has a property P of a union type of the types of P from each type in U. +str = x.commonPropertyType; // string +str = x.commonMethodType(str); // (a: string) => string so result should be string +strOrNum = x.commonPropertyDifferenType; +strOrNum = x.commonMethodDifferentReturnType(str); // string | union +x.commonMethodDifferentParameterType; // No error - property exists +x.commonMethodDifferentParameterType(strOrNum); // error - no call signatures because the type of this property is ((a: string) => string) | (a: number) => number + // and the call signatures arent identical +num = x.commonMethodWithTypeParameter(num); +num = x.commonMethodWithOwnTypeParameter(num); +str = x.commonMethodWithOwnTypeParameter(str); +strOrNum = x.commonMethodWithOwnTypeParameter(strOrNum); + +x.propertyOnlyInI1; // error +x.propertyOnlyInI2; // error +x.methodOnlyInI1("hello"); // error +x.methodOnlyInI2(10); // error + +//// [unionTypeMembers.js] +// a union type U has those members that are present in every one of its constituent types, +// with types that are unions of the respective members in the constituent types +var x; +var str; +var num; +var strOrNum; +// If each type in U has a property P, U has a property P of a union type of the types of P from each type in U. +str = x.commonPropertyType; // string +str = x.commonMethodType(str); // (a: string) => string so result should be string +strOrNum = x.commonPropertyDifferenType; +strOrNum = x.commonMethodDifferentReturnType(str); // string | union +x.commonMethodDifferentParameterType; // No error - property exists +x.commonMethodDifferentParameterType(strOrNum); // error - no call signatures because the type of this property is ((a: string) => string) | (a: number) => number +// and the call signatures arent identical +num = x.commonMethodWithTypeParameter(num); +num = x.commonMethodWithOwnTypeParameter(num); +str = x.commonMethodWithOwnTypeParameter(str); +strOrNum = x.commonMethodWithOwnTypeParameter(strOrNum); +x.propertyOnlyInI1; // error +x.propertyOnlyInI2; // error +x.methodOnlyInI1("hello"); // error +x.methodOnlyInI2(10); // error diff --git a/tests/cases/conformance/types/union/unionTypeEquivalence.ts b/tests/cases/conformance/types/union/unionTypeEquivalence.ts index 0905fde17f8..71fd6d91b65 100644 --- a/tests/cases/conformance/types/union/unionTypeEquivalence.ts +++ b/tests/cases/conformance/types/union/unionTypeEquivalence.ts @@ -1,6 +1,6 @@ // A | B is equivalent to A if B is a subtype of A class C { } -class D extends C { } +class D extends C { foo() { } } var x: C; var x : C | D; diff --git a/tests/cases/conformance/types/union/unionTypeMembers.ts b/tests/cases/conformance/types/union/unionTypeMembers.ts new file mode 100644 index 00000000000..73c6867e9ac --- /dev/null +++ b/tests/cases/conformance/types/union/unionTypeMembers.ts @@ -0,0 +1,54 @@ +interface I1 { + commonMethodType(a: string): string; + commonPropertyType: string; + + commonMethodDifferentParameterType(a: string): string; + commonMethodDifferentReturnType(a: string): string; + commonPropertyDifferenType: string; + + commonMethodWithTypeParameter(a: T): T; + commonMethodWithOwnTypeParameter(a: U): U; + + methodOnlyInI1(a: string): string; + propertyOnlyInI1: string; +} + +interface I2 { + commonMethodType(a: string): string; + commonPropertyType: string; + + commonMethodDifferentParameterType(a: number): number; + commonMethodDifferentReturnType(a: string): number; + commonPropertyDifferenType: number; + + commonMethodWithTypeParameter(a: T): T; + commonMethodWithOwnTypeParameter(a: U): U; + + methodOnlyInI2(a: string): string; + propertyOnlyInI2: string; +} + +// a union type U has those members that are present in every one of its constituent types, +// with types that are unions of the respective members in the constituent types +var x : I1 | I2; +var str: string; +var num: number; +var strOrNum: string | number; + +// If each type in U has a property P, U has a property P of a union type of the types of P from each type in U. +str = x.commonPropertyType; // string +str = x.commonMethodType(str); // (a: string) => string so result should be string +strOrNum = x.commonPropertyDifferenType; +strOrNum = x.commonMethodDifferentReturnType(str); // string | union +x.commonMethodDifferentParameterType; // No error - property exists +x.commonMethodDifferentParameterType(strOrNum); // error - no call signatures because the type of this property is ((a: string) => string) | (a: number) => number + // and the call signatures arent identical +num = x.commonMethodWithTypeParameter(num); +num = x.commonMethodWithOwnTypeParameter(num); +str = x.commonMethodWithOwnTypeParameter(str); +strOrNum = x.commonMethodWithOwnTypeParameter(strOrNum); + +x.propertyOnlyInI1; // error +x.propertyOnlyInI2; // error +x.methodOnlyInI1("hello"); // error +x.methodOnlyInI2(10); // error \ No newline at end of file From 2b8342bd79352b05403e769cb79da15d9444e7b1 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 3 Nov 2014 13:20:55 -0800 Subject: [PATCH 07/15] Tests for union of call signatures If each type in U has call signatures and the sets of call signatures are identical ignoring return types, U has the same set of call signatures, but with return types that are unions of the return types of the respective call signatures from each type in U. --- .../unionTypeCallSignatures.errors.txt | 178 ++++++++++++++++++ .../reference/unionTypeCallSignatures.js | 132 +++++++++++++ .../types/union/unionTypeCallSignatures.ts | 70 +++++++ 3 files changed, 380 insertions(+) create mode 100644 tests/baselines/reference/unionTypeCallSignatures.errors.txt create mode 100644 tests/baselines/reference/unionTypeCallSignatures.js create mode 100644 tests/cases/conformance/types/union/unionTypeCallSignatures.ts diff --git a/tests/baselines/reference/unionTypeCallSignatures.errors.txt b/tests/baselines/reference/unionTypeCallSignatures.errors.txt new file mode 100644 index 00000000000..313cd477187 --- /dev/null +++ b/tests/baselines/reference/unionTypeCallSignatures.errors.txt @@ -0,0 +1,178 @@ +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(9,43): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(10,29): error TS2345: Argument of type 'boolean' is not assignable to parameter of type 'string'. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(15,29): error TS2345: Argument of type 'boolean' is not assignable to parameter of type 'string'. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(16,1): error TS2346: Supplied parameters do not match any signature of call target. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(19,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(20,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(21,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(24,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(25,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(26,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(29,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(30,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(31,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(36,49): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(37,12): error TS2346: Supplied parameters do not match any signature of call target. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(40,12): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(41,12): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(42,12): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(43,12): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(46,12): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(47,12): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(48,12): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(49,12): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(55,45): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(56,12): error TS2346: Supplied parameters do not match any signature of call target. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(59,12): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(60,12): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(61,12): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(62,12): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(63,12): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(66,12): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(67,12): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(68,12): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(69,12): error TS2349: Cannot invoke an expression whose type lacks a call signature. +tests/cases/conformance/types/union/unionTypeCallSignatures.ts(70,12): error TS2349: Cannot invoke an expression whose type lacks a call signature. + + +==== tests/cases/conformance/types/union/unionTypeCallSignatures.ts (35 errors) ==== + var numOrDate: number | Date; + var strOrBoolean: string | boolean; + var strOrNum: string | number; + + // If each type in U has call signatures and the sets of call signatures are identical ignoring return types, + // U has the same set of call signatures, but with return types that are unions of the return types of the respective call signatures from each type in U. + var unionOfDifferentReturnType: { (a: number): number; } | { (a: number): Date; }; + numOrDate = unionOfDifferentReturnType(10); + strOrBoolean = unionOfDifferentReturnType("hello"); // error + ~~~~~~~ +!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. + unionOfDifferentReturnType1(true); // error in type of parameter + ~~~~ +!!! error TS2345: Argument of type 'boolean' is not assignable to parameter of type 'string'. + + var unionOfDifferentReturnType1: { (a: number): number; (a: string): string; } | { (a: number): Date; (a: string): boolean; }; + numOrDate = unionOfDifferentReturnType1(10); + strOrBoolean = unionOfDifferentReturnType1("hello"); + unionOfDifferentReturnType1(true); // error in type of parameter + ~~~~ +!!! error TS2345: Argument of type 'boolean' is not assignable to parameter of type 'string'. + unionOfDifferentReturnType1(); // error missing parameter + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2346: Supplied parameters do not match any signature of call target. + + var unionOfDifferentParameterTypes: { (a: number): number; } | { (a: string): Date; }; + unionOfDifferentParameterTypes(10);// error - no call signatures + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + unionOfDifferentParameterTypes("hello");// error - no call signatures + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + unionOfDifferentParameterTypes();// error - no call signatures + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + + var unionOfDifferentNumberOfSignatures: { (a: number): number; } | { (a: number): Date; (a: string): boolean; }; + unionOfDifferentNumberOfSignatures(); // error - no call signatures + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + unionOfDifferentNumberOfSignatures(10); // error - no call signatures + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + unionOfDifferentNumberOfSignatures("hello"); // error - no call signatures + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + + var unionWithDifferentParameterCount: { (a: string): string; } | { (a: string, b: number): number; } ; + unionWithDifferentParameterCount();// no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + unionWithDifferentParameterCount("hello");// no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + unionWithDifferentParameterCount("hello", 10);// no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + + var unionWithOptionalParameter1: { (a: string, b?: number): string; } | { (a: string, b?: number): number; }; + strOrNum = unionWithOptionalParameter1('hello'); + strOrNum = unionWithOptionalParameter1('hello', 10); + strOrNum = unionWithOptionalParameter1('hello', "hello"); // error in parameter type + ~~~~~~~ +!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. + strOrNum = unionWithOptionalParameter1(); // error + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2346: Supplied parameters do not match any signature of call target. + + var unionWithOptionalParameter2: { (a: string, b?: number): string; } | { (a: string, b: number): number }; + strOrNum = unionWithOptionalParameter2('hello'); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + strOrNum = unionWithOptionalParameter2('hello', 10); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + strOrNum = unionWithOptionalParameter2('hello', "hello"); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + strOrNum = unionWithOptionalParameter2(); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + + var unionWithOptionalParameter3: { (a: string, b?: number): string; } | { (a: string): number; }; + strOrNum = unionWithOptionalParameter3('hello'); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + strOrNum = unionWithOptionalParameter3('hello', 10); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + strOrNum = unionWithOptionalParameter3('hello', "hello"); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + strOrNum = unionWithOptionalParameter3(); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + + var unionWithRestParameter1: { (a: string, ...b: number[]): string; } | { (a: string, ...b: number[]): number }; + strOrNum = unionWithRestParameter1('hello'); + strOrNum = unionWithRestParameter1('hello', 10); + strOrNum = unionWithRestParameter1('hello', 10, 11); + strOrNum = unionWithRestParameter1('hello', "hello"); // error in parameter type + ~~~~~~~ +!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. + strOrNum = unionWithRestParameter1(); // error + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2346: Supplied parameters do not match any signature of call target. + + var unionWithRestParameter2: { (a: string, ...b: number[]): string; } | { (a: string, b: number): number }; + strOrNum = unionWithRestParameter2('hello'); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + strOrNum = unionWithRestParameter2('hello', 10); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + strOrNum = unionWithRestParameter2('hello', 10, 11); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + strOrNum = unionWithRestParameter2('hello', "hello"); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + strOrNum = unionWithRestParameter2(); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + + var unionWithRestParameter3: { (a: string, ...b: number[]): string; } | { (a: string): number }; + strOrNum = unionWithRestParameter3('hello'); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + strOrNum = unionWithRestParameter3('hello', 10); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + strOrNum = unionWithRestParameter3('hello', 10, 11); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + strOrNum = unionWithRestParameter3('hello', "hello"); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. + strOrNum = unionWithRestParameter3(); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. \ No newline at end of file diff --git a/tests/baselines/reference/unionTypeCallSignatures.js b/tests/baselines/reference/unionTypeCallSignatures.js new file mode 100644 index 00000000000..a4000038ce6 --- /dev/null +++ b/tests/baselines/reference/unionTypeCallSignatures.js @@ -0,0 +1,132 @@ +//// [unionTypeCallSignatures.ts] +var numOrDate: number | Date; +var strOrBoolean: string | boolean; +var strOrNum: string | number; + +// If each type in U has call signatures and the sets of call signatures are identical ignoring return types, +// U has the same set of call signatures, but with return types that are unions of the return types of the respective call signatures from each type in U. +var unionOfDifferentReturnType: { (a: number): number; } | { (a: number): Date; }; +numOrDate = unionOfDifferentReturnType(10); +strOrBoolean = unionOfDifferentReturnType("hello"); // error +unionOfDifferentReturnType1(true); // error in type of parameter + +var unionOfDifferentReturnType1: { (a: number): number; (a: string): string; } | { (a: number): Date; (a: string): boolean; }; +numOrDate = unionOfDifferentReturnType1(10); +strOrBoolean = unionOfDifferentReturnType1("hello"); +unionOfDifferentReturnType1(true); // error in type of parameter +unionOfDifferentReturnType1(); // error missing parameter + +var unionOfDifferentParameterTypes: { (a: number): number; } | { (a: string): Date; }; +unionOfDifferentParameterTypes(10);// error - no call signatures +unionOfDifferentParameterTypes("hello");// error - no call signatures +unionOfDifferentParameterTypes();// error - no call signatures + +var unionOfDifferentNumberOfSignatures: { (a: number): number; } | { (a: number): Date; (a: string): boolean; }; +unionOfDifferentNumberOfSignatures(); // error - no call signatures +unionOfDifferentNumberOfSignatures(10); // error - no call signatures +unionOfDifferentNumberOfSignatures("hello"); // error - no call signatures + + var unionWithDifferentParameterCount: { (a: string): string; } | { (a: string, b: number): number; } ; +unionWithDifferentParameterCount();// no call signature +unionWithDifferentParameterCount("hello");// no call signature +unionWithDifferentParameterCount("hello", 10);// no call signature + + var unionWithOptionalParameter1: { (a: string, b?: number): string; } | { (a: string, b?: number): number; }; +strOrNum = unionWithOptionalParameter1('hello'); +strOrNum = unionWithOptionalParameter1('hello', 10); +strOrNum = unionWithOptionalParameter1('hello', "hello"); // error in parameter type +strOrNum = unionWithOptionalParameter1(); // error + +var unionWithOptionalParameter2: { (a: string, b?: number): string; } | { (a: string, b: number): number }; +strOrNum = unionWithOptionalParameter2('hello'); // error no call signature +strOrNum = unionWithOptionalParameter2('hello', 10); // error no call signature +strOrNum = unionWithOptionalParameter2('hello', "hello"); // error no call signature +strOrNum = unionWithOptionalParameter2(); // error no call signature + +var unionWithOptionalParameter3: { (a: string, b?: number): string; } | { (a: string): number; }; +strOrNum = unionWithOptionalParameter3('hello'); // error no call signature +strOrNum = unionWithOptionalParameter3('hello', 10); // error no call signature +strOrNum = unionWithOptionalParameter3('hello', "hello"); // error no call signature +strOrNum = unionWithOptionalParameter3(); // error no call signature + +var unionWithRestParameter1: { (a: string, ...b: number[]): string; } | { (a: string, ...b: number[]): number }; +strOrNum = unionWithRestParameter1('hello'); +strOrNum = unionWithRestParameter1('hello', 10); +strOrNum = unionWithRestParameter1('hello', 10, 11); +strOrNum = unionWithRestParameter1('hello', "hello"); // error in parameter type +strOrNum = unionWithRestParameter1(); // error + +var unionWithRestParameter2: { (a: string, ...b: number[]): string; } | { (a: string, b: number): number }; +strOrNum = unionWithRestParameter2('hello'); // error no call signature +strOrNum = unionWithRestParameter2('hello', 10); // error no call signature +strOrNum = unionWithRestParameter2('hello', 10, 11); // error no call signature +strOrNum = unionWithRestParameter2('hello', "hello"); // error no call signature +strOrNum = unionWithRestParameter2(); // error no call signature + +var unionWithRestParameter3: { (a: string, ...b: number[]): string; } | { (a: string): number }; +strOrNum = unionWithRestParameter3('hello'); // error no call signature +strOrNum = unionWithRestParameter3('hello', 10); // error no call signature +strOrNum = unionWithRestParameter3('hello', 10, 11); // error no call signature +strOrNum = unionWithRestParameter3('hello', "hello"); // error no call signature +strOrNum = unionWithRestParameter3(); // error no call signature + +//// [unionTypeCallSignatures.js] +var numOrDate; +var strOrBoolean; +var strOrNum; +// If each type in U has call signatures and the sets of call signatures are identical ignoring return types, +// U has the same set of call signatures, but with return types that are unions of the return types of the respective call signatures from each type in U. +var unionOfDifferentReturnType; +numOrDate = unionOfDifferentReturnType(10); +strOrBoolean = unionOfDifferentReturnType("hello"); // error +unionOfDifferentReturnType1(true); // error in type of parameter +var unionOfDifferentReturnType1; +numOrDate = unionOfDifferentReturnType1(10); +strOrBoolean = unionOfDifferentReturnType1("hello"); +unionOfDifferentReturnType1(true); // error in type of parameter +unionOfDifferentReturnType1(); // error missing parameter +var unionOfDifferentParameterTypes; +unionOfDifferentParameterTypes(10); // error - no call signatures +unionOfDifferentParameterTypes("hello"); // error - no call signatures +unionOfDifferentParameterTypes(); // error - no call signatures +var unionOfDifferentNumberOfSignatures; +unionOfDifferentNumberOfSignatures(); // error - no call signatures +unionOfDifferentNumberOfSignatures(10); // error - no call signatures +unionOfDifferentNumberOfSignatures("hello"); // error - no call signatures +var unionWithDifferentParameterCount; +unionWithDifferentParameterCount(); // no call signature +unionWithDifferentParameterCount("hello"); // no call signature +unionWithDifferentParameterCount("hello", 10); // no call signature +var unionWithOptionalParameter1; +strOrNum = unionWithOptionalParameter1('hello'); +strOrNum = unionWithOptionalParameter1('hello', 10); +strOrNum = unionWithOptionalParameter1('hello', "hello"); // error in parameter type +strOrNum = unionWithOptionalParameter1(); // error +var unionWithOptionalParameter2; +strOrNum = unionWithOptionalParameter2('hello'); // error no call signature +strOrNum = unionWithOptionalParameter2('hello', 10); // error no call signature +strOrNum = unionWithOptionalParameter2('hello', "hello"); // error no call signature +strOrNum = unionWithOptionalParameter2(); // error no call signature +var unionWithOptionalParameter3; +strOrNum = unionWithOptionalParameter3('hello'); // error no call signature +strOrNum = unionWithOptionalParameter3('hello', 10); // error no call signature +strOrNum = unionWithOptionalParameter3('hello', "hello"); // error no call signature +strOrNum = unionWithOptionalParameter3(); // error no call signature +var unionWithRestParameter1; +strOrNum = unionWithRestParameter1('hello'); +strOrNum = unionWithRestParameter1('hello', 10); +strOrNum = unionWithRestParameter1('hello', 10, 11); +strOrNum = unionWithRestParameter1('hello', "hello"); // error in parameter type +strOrNum = unionWithRestParameter1(); // error +var unionWithRestParameter2; +strOrNum = unionWithRestParameter2('hello'); // error no call signature +strOrNum = unionWithRestParameter2('hello', 10); // error no call signature +strOrNum = unionWithRestParameter2('hello', 10, 11); // error no call signature +strOrNum = unionWithRestParameter2('hello', "hello"); // error no call signature +strOrNum = unionWithRestParameter2(); // error no call signature +var unionWithRestParameter3; +strOrNum = unionWithRestParameter3('hello'); // error no call signature +strOrNum = unionWithRestParameter3('hello', 10); // error no call signature +strOrNum = unionWithRestParameter3('hello', 10, 11); // error no call signature +strOrNum = unionWithRestParameter3('hello', "hello"); // error no call signature +strOrNum = unionWithRestParameter3(); // error no call signature diff --git a/tests/cases/conformance/types/union/unionTypeCallSignatures.ts b/tests/cases/conformance/types/union/unionTypeCallSignatures.ts new file mode 100644 index 00000000000..1261de3299e --- /dev/null +++ b/tests/cases/conformance/types/union/unionTypeCallSignatures.ts @@ -0,0 +1,70 @@ +var numOrDate: number | Date; +var strOrBoolean: string | boolean; +var strOrNum: string | number; + +// If each type in U has call signatures and the sets of call signatures are identical ignoring return types, +// U has the same set of call signatures, but with return types that are unions of the return types of the respective call signatures from each type in U. +var unionOfDifferentReturnType: { (a: number): number; } | { (a: number): Date; }; +numOrDate = unionOfDifferentReturnType(10); +strOrBoolean = unionOfDifferentReturnType("hello"); // error +unionOfDifferentReturnType1(true); // error in type of parameter + +var unionOfDifferentReturnType1: { (a: number): number; (a: string): string; } | { (a: number): Date; (a: string): boolean; }; +numOrDate = unionOfDifferentReturnType1(10); +strOrBoolean = unionOfDifferentReturnType1("hello"); +unionOfDifferentReturnType1(true); // error in type of parameter +unionOfDifferentReturnType1(); // error missing parameter + +var unionOfDifferentParameterTypes: { (a: number): number; } | { (a: string): Date; }; +unionOfDifferentParameterTypes(10);// error - no call signatures +unionOfDifferentParameterTypes("hello");// error - no call signatures +unionOfDifferentParameterTypes();// error - no call signatures + +var unionOfDifferentNumberOfSignatures: { (a: number): number; } | { (a: number): Date; (a: string): boolean; }; +unionOfDifferentNumberOfSignatures(); // error - no call signatures +unionOfDifferentNumberOfSignatures(10); // error - no call signatures +unionOfDifferentNumberOfSignatures("hello"); // error - no call signatures + + var unionWithDifferentParameterCount: { (a: string): string; } | { (a: string, b: number): number; } ; +unionWithDifferentParameterCount();// no call signature +unionWithDifferentParameterCount("hello");// no call signature +unionWithDifferentParameterCount("hello", 10);// no call signature + + var unionWithOptionalParameter1: { (a: string, b?: number): string; } | { (a: string, b?: number): number; }; +strOrNum = unionWithOptionalParameter1('hello'); +strOrNum = unionWithOptionalParameter1('hello', 10); +strOrNum = unionWithOptionalParameter1('hello', "hello"); // error in parameter type +strOrNum = unionWithOptionalParameter1(); // error + +var unionWithOptionalParameter2: { (a: string, b?: number): string; } | { (a: string, b: number): number }; +strOrNum = unionWithOptionalParameter2('hello'); // error no call signature +strOrNum = unionWithOptionalParameter2('hello', 10); // error no call signature +strOrNum = unionWithOptionalParameter2('hello', "hello"); // error no call signature +strOrNum = unionWithOptionalParameter2(); // error no call signature + +var unionWithOptionalParameter3: { (a: string, b?: number): string; } | { (a: string): number; }; +strOrNum = unionWithOptionalParameter3('hello'); // error no call signature +strOrNum = unionWithOptionalParameter3('hello', 10); // error no call signature +strOrNum = unionWithOptionalParameter3('hello', "hello"); // error no call signature +strOrNum = unionWithOptionalParameter3(); // error no call signature + +var unionWithRestParameter1: { (a: string, ...b: number[]): string; } | { (a: string, ...b: number[]): number }; +strOrNum = unionWithRestParameter1('hello'); +strOrNum = unionWithRestParameter1('hello', 10); +strOrNum = unionWithRestParameter1('hello', 10, 11); +strOrNum = unionWithRestParameter1('hello', "hello"); // error in parameter type +strOrNum = unionWithRestParameter1(); // error + +var unionWithRestParameter2: { (a: string, ...b: number[]): string; } | { (a: string, b: number): number }; +strOrNum = unionWithRestParameter2('hello'); // error no call signature +strOrNum = unionWithRestParameter2('hello', 10); // error no call signature +strOrNum = unionWithRestParameter2('hello', 10, 11); // error no call signature +strOrNum = unionWithRestParameter2('hello', "hello"); // error no call signature +strOrNum = unionWithRestParameter2(); // error no call signature + +var unionWithRestParameter3: { (a: string, ...b: number[]): string; } | { (a: string): number }; +strOrNum = unionWithRestParameter3('hello'); // error no call signature +strOrNum = unionWithRestParameter3('hello', 10); // error no call signature +strOrNum = unionWithRestParameter3('hello', 10, 11); // error no call signature +strOrNum = unionWithRestParameter3('hello', "hello"); // error no call signature +strOrNum = unionWithRestParameter3(); // error no call signature \ No newline at end of file From c2b2c306afbe44bd422138e254b2a0db486bc11f Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 3 Nov 2014 13:23:06 -0800 Subject: [PATCH 08/15] Tests for union of construct signatures If each type in U has construct signatures and the sets of construct signatures are identical ignoring return types, U has the same set of construct signatures, but with return types that are unions of the return types of the respective construct signatures from each type in U. --- .../unionTypeConstructSignatures.errors.txt | 178 ++++++++++++++++++ .../reference/unionTypeConstructSignatures.js | 132 +++++++++++++ .../union/unionTypeConstructSignatures.ts | 70 +++++++ 3 files changed, 380 insertions(+) create mode 100644 tests/baselines/reference/unionTypeConstructSignatures.errors.txt create mode 100644 tests/baselines/reference/unionTypeConstructSignatures.js create mode 100644 tests/cases/conformance/types/union/unionTypeConstructSignatures.ts diff --git a/tests/baselines/reference/unionTypeConstructSignatures.errors.txt b/tests/baselines/reference/unionTypeConstructSignatures.errors.txt new file mode 100644 index 00000000000..dd46564d779 --- /dev/null +++ b/tests/baselines/reference/unionTypeConstructSignatures.errors.txt @@ -0,0 +1,178 @@ +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(9,47): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(10,33): error TS2345: Argument of type 'boolean' is not assignable to parameter of type 'string'. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(15,33): error TS2345: Argument of type 'boolean' is not assignable to parameter of type 'string'. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(16,1): error TS2346: Supplied parameters do not match any signature of call target. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(19,1): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(20,1): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(21,1): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(24,1): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(25,1): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(26,1): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(29,1): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(30,1): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(31,1): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(36,53): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(37,12): error TS2346: Supplied parameters do not match any signature of call target. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(40,12): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(41,12): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(42,12): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(43,12): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(46,12): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(47,12): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(48,12): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(49,12): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(55,49): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(56,12): error TS2346: Supplied parameters do not match any signature of call target. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(59,12): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(60,12): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(61,12): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(62,12): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(63,12): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(66,12): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(67,12): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(68,12): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(69,12): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(70,12): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + + +==== tests/cases/conformance/types/union/unionTypeConstructSignatures.ts (35 errors) ==== + var numOrDate: number | Date; + var strOrBoolean: string | boolean; + var strOrNum: string | number; + + // If each type in U has construct signatures and the sets of construct signatures are identical ignoring return types, + // U has the same set of construct signatures, but with return types that are unions of the return types of the respective construct signatures from each type in U. + var unionOfDifferentReturnType: { new (a: number): number; } | { new (a: number): Date; }; + numOrDate = new unionOfDifferentReturnType(10); + strOrBoolean = new unionOfDifferentReturnType("hello"); // error + ~~~~~~~ +!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. + new unionOfDifferentReturnType1(true); // error in type of parameter + ~~~~ +!!! error TS2345: Argument of type 'boolean' is not assignable to parameter of type 'string'. + + var unionOfDifferentReturnType1: { new (a: number): number; new (a: string): string; } | { new (a: number): Date; new (a: string): boolean; }; + numOrDate = new unionOfDifferentReturnType1(10); + strOrBoolean = new unionOfDifferentReturnType1("hello"); + new unionOfDifferentReturnType1(true); // error in type of parameter + ~~~~ +!!! error TS2345: Argument of type 'boolean' is not assignable to parameter of type 'string'. + new unionOfDifferentReturnType1(); // error missing parameter + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2346: Supplied parameters do not match any signature of call target. + + var unionOfDifferentParameterTypes: { new (a: number): number; } | { new (a: string): Date; }; + new unionOfDifferentParameterTypes(10);// error - no call signatures + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + new unionOfDifferentParameterTypes("hello");// error - no call signatures + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + new unionOfDifferentParameterTypes();// error - no call signatures + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + + var unionOfDifferentNumberOfSignatures: { new (a: number): number; } | { new (a: number): Date; new (a: string): boolean; }; + new unionOfDifferentNumberOfSignatures(); // error - no call signatures + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + new unionOfDifferentNumberOfSignatures(10); // error - no call signatures + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + new unionOfDifferentNumberOfSignatures("hello"); // error - no call signatures + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + + var unionWithDifferentParameterCount: { new (a: string): string; } | { new (a: string, b: number): number; }; + new unionWithDifferentParameterCount();// no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + new unionWithDifferentParameterCount("hello");// no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + new unionWithDifferentParameterCount("hello", 10);// no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + + var unionWithOptionalParameter1: { new (a: string, b?: number): string; } | { new (a: string, b?: number): number; }; + strOrNum = new unionWithOptionalParameter1('hello'); + strOrNum = new unionWithOptionalParameter1('hello', 10); + strOrNum = new unionWithOptionalParameter1('hello', "hello"); // error in parameter type + ~~~~~~~ +!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. + strOrNum = new unionWithOptionalParameter1(); // error + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2346: Supplied parameters do not match any signature of call target. + + var unionWithOptionalParameter2: { new (a: string, b?: number): string; } | { new (a: string, b: number): number }; + strOrNum = new unionWithOptionalParameter2('hello'); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + strOrNum = new unionWithOptionalParameter2('hello', 10); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + strOrNum = new unionWithOptionalParameter2('hello', "hello"); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + strOrNum = new unionWithOptionalParameter2(); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + + var unionWithOptionalParameter3: { new (a: string, b?: number): string; } | { new (a: string): number; }; + strOrNum = new unionWithOptionalParameter3('hello'); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + strOrNum = new unionWithOptionalParameter3('hello', 10); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + strOrNum = new unionWithOptionalParameter3('hello', "hello"); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + strOrNum = new unionWithOptionalParameter3(); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + + var unionWithRestParameter1: { new (a: string, ...b: number[]): string; } | { new (a: string, ...b: number[]): number }; + strOrNum = new unionWithRestParameter1('hello'); + strOrNum = new unionWithRestParameter1('hello', 10); + strOrNum = new unionWithRestParameter1('hello', 10, 11); + strOrNum = new unionWithRestParameter1('hello', "hello"); // error in parameter type + ~~~~~~~ +!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. + strOrNum = new unionWithRestParameter1(); // error + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2346: Supplied parameters do not match any signature of call target. + + var unionWithRestParameter2: { new (a: string, ...b: number[]): string; } | { new (a: string, b: number): number }; + strOrNum = new unionWithRestParameter2('hello'); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + strOrNum = new unionWithRestParameter2('hello', 10); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + strOrNum = new unionWithRestParameter2('hello', 10, 11); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + strOrNum = new unionWithRestParameter2('hello', "hello"); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + strOrNum = new unionWithRestParameter2(); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + + var unionWithRestParameter3: { new (a: string, ...b: number[]): string; } | { new (a: string): number }; + strOrNum = new unionWithRestParameter3('hello'); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + strOrNum = new unionWithRestParameter3('hello', 10); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + strOrNum = new unionWithRestParameter3('hello', 10, 11); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + strOrNum = new unionWithRestParameter3('hello', "hello"); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. + strOrNum = new unionWithRestParameter3(); // error no call signature + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature. \ No newline at end of file diff --git a/tests/baselines/reference/unionTypeConstructSignatures.js b/tests/baselines/reference/unionTypeConstructSignatures.js new file mode 100644 index 00000000000..83c3df44603 --- /dev/null +++ b/tests/baselines/reference/unionTypeConstructSignatures.js @@ -0,0 +1,132 @@ +//// [unionTypeConstructSignatures.ts] +var numOrDate: number | Date; +var strOrBoolean: string | boolean; +var strOrNum: string | number; + +// If each type in U has construct signatures and the sets of construct signatures are identical ignoring return types, +// U has the same set of construct signatures, but with return types that are unions of the return types of the respective construct signatures from each type in U. +var unionOfDifferentReturnType: { new (a: number): number; } | { new (a: number): Date; }; +numOrDate = new unionOfDifferentReturnType(10); +strOrBoolean = new unionOfDifferentReturnType("hello"); // error +new unionOfDifferentReturnType1(true); // error in type of parameter + +var unionOfDifferentReturnType1: { new (a: number): number; new (a: string): string; } | { new (a: number): Date; new (a: string): boolean; }; +numOrDate = new unionOfDifferentReturnType1(10); +strOrBoolean = new unionOfDifferentReturnType1("hello"); +new unionOfDifferentReturnType1(true); // error in type of parameter +new unionOfDifferentReturnType1(); // error missing parameter + +var unionOfDifferentParameterTypes: { new (a: number): number; } | { new (a: string): Date; }; +new unionOfDifferentParameterTypes(10);// error - no call signatures +new unionOfDifferentParameterTypes("hello");// error - no call signatures +new unionOfDifferentParameterTypes();// error - no call signatures + +var unionOfDifferentNumberOfSignatures: { new (a: number): number; } | { new (a: number): Date; new (a: string): boolean; }; +new unionOfDifferentNumberOfSignatures(); // error - no call signatures +new unionOfDifferentNumberOfSignatures(10); // error - no call signatures +new unionOfDifferentNumberOfSignatures("hello"); // error - no call signatures + +var unionWithDifferentParameterCount: { new (a: string): string; } | { new (a: string, b: number): number; }; +new unionWithDifferentParameterCount();// no call signature +new unionWithDifferentParameterCount("hello");// no call signature +new unionWithDifferentParameterCount("hello", 10);// no call signature + +var unionWithOptionalParameter1: { new (a: string, b?: number): string; } | { new (a: string, b?: number): number; }; +strOrNum = new unionWithOptionalParameter1('hello'); +strOrNum = new unionWithOptionalParameter1('hello', 10); +strOrNum = new unionWithOptionalParameter1('hello', "hello"); // error in parameter type +strOrNum = new unionWithOptionalParameter1(); // error + +var unionWithOptionalParameter2: { new (a: string, b?: number): string; } | { new (a: string, b: number): number }; +strOrNum = new unionWithOptionalParameter2('hello'); // error no call signature +strOrNum = new unionWithOptionalParameter2('hello', 10); // error no call signature +strOrNum = new unionWithOptionalParameter2('hello', "hello"); // error no call signature +strOrNum = new unionWithOptionalParameter2(); // error no call signature + +var unionWithOptionalParameter3: { new (a: string, b?: number): string; } | { new (a: string): number; }; +strOrNum = new unionWithOptionalParameter3('hello'); // error no call signature +strOrNum = new unionWithOptionalParameter3('hello', 10); // error no call signature +strOrNum = new unionWithOptionalParameter3('hello', "hello"); // error no call signature +strOrNum = new unionWithOptionalParameter3(); // error no call signature + +var unionWithRestParameter1: { new (a: string, ...b: number[]): string; } | { new (a: string, ...b: number[]): number }; +strOrNum = new unionWithRestParameter1('hello'); +strOrNum = new unionWithRestParameter1('hello', 10); +strOrNum = new unionWithRestParameter1('hello', 10, 11); +strOrNum = new unionWithRestParameter1('hello', "hello"); // error in parameter type +strOrNum = new unionWithRestParameter1(); // error + +var unionWithRestParameter2: { new (a: string, ...b: number[]): string; } | { new (a: string, b: number): number }; +strOrNum = new unionWithRestParameter2('hello'); // error no call signature +strOrNum = new unionWithRestParameter2('hello', 10); // error no call signature +strOrNum = new unionWithRestParameter2('hello', 10, 11); // error no call signature +strOrNum = new unionWithRestParameter2('hello', "hello"); // error no call signature +strOrNum = new unionWithRestParameter2(); // error no call signature + +var unionWithRestParameter3: { new (a: string, ...b: number[]): string; } | { new (a: string): number }; +strOrNum = new unionWithRestParameter3('hello'); // error no call signature +strOrNum = new unionWithRestParameter3('hello', 10); // error no call signature +strOrNum = new unionWithRestParameter3('hello', 10, 11); // error no call signature +strOrNum = new unionWithRestParameter3('hello', "hello"); // error no call signature +strOrNum = new unionWithRestParameter3(); // error no call signature + +//// [unionTypeConstructSignatures.js] +var numOrDate; +var strOrBoolean; +var strOrNum; +// If each type in U has construct signatures and the sets of construct signatures are identical ignoring return types, +// U has the same set of construct signatures, but with return types that are unions of the return types of the respective construct signatures from each type in U. +var unionOfDifferentReturnType; +numOrDate = new unionOfDifferentReturnType(10); +strOrBoolean = new unionOfDifferentReturnType("hello"); // error +new unionOfDifferentReturnType1(true); // error in type of parameter +var unionOfDifferentReturnType1; +numOrDate = new unionOfDifferentReturnType1(10); +strOrBoolean = new unionOfDifferentReturnType1("hello"); +new unionOfDifferentReturnType1(true); // error in type of parameter +new unionOfDifferentReturnType1(); // error missing parameter +var unionOfDifferentParameterTypes; +new unionOfDifferentParameterTypes(10); // error - no call signatures +new unionOfDifferentParameterTypes("hello"); // error - no call signatures +new unionOfDifferentParameterTypes(); // error - no call signatures +var unionOfDifferentNumberOfSignatures; +new unionOfDifferentNumberOfSignatures(); // error - no call signatures +new unionOfDifferentNumberOfSignatures(10); // error - no call signatures +new unionOfDifferentNumberOfSignatures("hello"); // error - no call signatures +var unionWithDifferentParameterCount; +new unionWithDifferentParameterCount(); // no call signature +new unionWithDifferentParameterCount("hello"); // no call signature +new unionWithDifferentParameterCount("hello", 10); // no call signature +var unionWithOptionalParameter1; +strOrNum = new unionWithOptionalParameter1('hello'); +strOrNum = new unionWithOptionalParameter1('hello', 10); +strOrNum = new unionWithOptionalParameter1('hello', "hello"); // error in parameter type +strOrNum = new unionWithOptionalParameter1(); // error +var unionWithOptionalParameter2; +strOrNum = new unionWithOptionalParameter2('hello'); // error no call signature +strOrNum = new unionWithOptionalParameter2('hello', 10); // error no call signature +strOrNum = new unionWithOptionalParameter2('hello', "hello"); // error no call signature +strOrNum = new unionWithOptionalParameter2(); // error no call signature +var unionWithOptionalParameter3; +strOrNum = new unionWithOptionalParameter3('hello'); // error no call signature +strOrNum = new unionWithOptionalParameter3('hello', 10); // error no call signature +strOrNum = new unionWithOptionalParameter3('hello', "hello"); // error no call signature +strOrNum = new unionWithOptionalParameter3(); // error no call signature +var unionWithRestParameter1; +strOrNum = new unionWithRestParameter1('hello'); +strOrNum = new unionWithRestParameter1('hello', 10); +strOrNum = new unionWithRestParameter1('hello', 10, 11); +strOrNum = new unionWithRestParameter1('hello', "hello"); // error in parameter type +strOrNum = new unionWithRestParameter1(); // error +var unionWithRestParameter2; +strOrNum = new unionWithRestParameter2('hello'); // error no call signature +strOrNum = new unionWithRestParameter2('hello', 10); // error no call signature +strOrNum = new unionWithRestParameter2('hello', 10, 11); // error no call signature +strOrNum = new unionWithRestParameter2('hello', "hello"); // error no call signature +strOrNum = new unionWithRestParameter2(); // error no call signature +var unionWithRestParameter3; +strOrNum = new unionWithRestParameter3('hello'); // error no call signature +strOrNum = new unionWithRestParameter3('hello', 10); // error no call signature +strOrNum = new unionWithRestParameter3('hello', 10, 11); // error no call signature +strOrNum = new unionWithRestParameter3('hello', "hello"); // error no call signature +strOrNum = new unionWithRestParameter3(); // error no call signature diff --git a/tests/cases/conformance/types/union/unionTypeConstructSignatures.ts b/tests/cases/conformance/types/union/unionTypeConstructSignatures.ts new file mode 100644 index 00000000000..a02ba610ff7 --- /dev/null +++ b/tests/cases/conformance/types/union/unionTypeConstructSignatures.ts @@ -0,0 +1,70 @@ +var numOrDate: number | Date; +var strOrBoolean: string | boolean; +var strOrNum: string | number; + +// If each type in U has construct signatures and the sets of construct signatures are identical ignoring return types, +// U has the same set of construct signatures, but with return types that are unions of the return types of the respective construct signatures from each type in U. +var unionOfDifferentReturnType: { new (a: number): number; } | { new (a: number): Date; }; +numOrDate = new unionOfDifferentReturnType(10); +strOrBoolean = new unionOfDifferentReturnType("hello"); // error +new unionOfDifferentReturnType1(true); // error in type of parameter + +var unionOfDifferentReturnType1: { new (a: number): number; new (a: string): string; } | { new (a: number): Date; new (a: string): boolean; }; +numOrDate = new unionOfDifferentReturnType1(10); +strOrBoolean = new unionOfDifferentReturnType1("hello"); +new unionOfDifferentReturnType1(true); // error in type of parameter +new unionOfDifferentReturnType1(); // error missing parameter + +var unionOfDifferentParameterTypes: { new (a: number): number; } | { new (a: string): Date; }; +new unionOfDifferentParameterTypes(10);// error - no call signatures +new unionOfDifferentParameterTypes("hello");// error - no call signatures +new unionOfDifferentParameterTypes();// error - no call signatures + +var unionOfDifferentNumberOfSignatures: { new (a: number): number; } | { new (a: number): Date; new (a: string): boolean; }; +new unionOfDifferentNumberOfSignatures(); // error - no call signatures +new unionOfDifferentNumberOfSignatures(10); // error - no call signatures +new unionOfDifferentNumberOfSignatures("hello"); // error - no call signatures + +var unionWithDifferentParameterCount: { new (a: string): string; } | { new (a: string, b: number): number; }; +new unionWithDifferentParameterCount();// no call signature +new unionWithDifferentParameterCount("hello");// no call signature +new unionWithDifferentParameterCount("hello", 10);// no call signature + +var unionWithOptionalParameter1: { new (a: string, b?: number): string; } | { new (a: string, b?: number): number; }; +strOrNum = new unionWithOptionalParameter1('hello'); +strOrNum = new unionWithOptionalParameter1('hello', 10); +strOrNum = new unionWithOptionalParameter1('hello', "hello"); // error in parameter type +strOrNum = new unionWithOptionalParameter1(); // error + +var unionWithOptionalParameter2: { new (a: string, b?: number): string; } | { new (a: string, b: number): number }; +strOrNum = new unionWithOptionalParameter2('hello'); // error no call signature +strOrNum = new unionWithOptionalParameter2('hello', 10); // error no call signature +strOrNum = new unionWithOptionalParameter2('hello', "hello"); // error no call signature +strOrNum = new unionWithOptionalParameter2(); // error no call signature + +var unionWithOptionalParameter3: { new (a: string, b?: number): string; } | { new (a: string): number; }; +strOrNum = new unionWithOptionalParameter3('hello'); // error no call signature +strOrNum = new unionWithOptionalParameter3('hello', 10); // error no call signature +strOrNum = new unionWithOptionalParameter3('hello', "hello"); // error no call signature +strOrNum = new unionWithOptionalParameter3(); // error no call signature + +var unionWithRestParameter1: { new (a: string, ...b: number[]): string; } | { new (a: string, ...b: number[]): number }; +strOrNum = new unionWithRestParameter1('hello'); +strOrNum = new unionWithRestParameter1('hello', 10); +strOrNum = new unionWithRestParameter1('hello', 10, 11); +strOrNum = new unionWithRestParameter1('hello', "hello"); // error in parameter type +strOrNum = new unionWithRestParameter1(); // error + +var unionWithRestParameter2: { new (a: string, ...b: number[]): string; } | { new (a: string, b: number): number }; +strOrNum = new unionWithRestParameter2('hello'); // error no call signature +strOrNum = new unionWithRestParameter2('hello', 10); // error no call signature +strOrNum = new unionWithRestParameter2('hello', 10, 11); // error no call signature +strOrNum = new unionWithRestParameter2('hello', "hello"); // error no call signature +strOrNum = new unionWithRestParameter2(); // error no call signature + +var unionWithRestParameter3: { new (a: string, ...b: number[]): string; } | { new (a: string): number }; +strOrNum = new unionWithRestParameter3('hello'); // error no call signature +strOrNum = new unionWithRestParameter3('hello', 10); // error no call signature +strOrNum = new unionWithRestParameter3('hello', 10, 11); // error no call signature +strOrNum = new unionWithRestParameter3('hello', "hello"); // error no call signature +strOrNum = new unionWithRestParameter3(); // error no call signature \ No newline at end of file From 49b5b5ab994b3e05924947a8eca2ba43d65cf006 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 3 Nov 2014 13:36:06 -0800 Subject: [PATCH 09/15] =?UTF-8?q?Tests=20for=20union=20of=20index=20signat?= =?UTF-8?q?ures:=20=E2=80=A2=09If=20each=20type=20in=20U=20has=20a=20strin?= =?UTF-8?q?g=20index=20signature,=20U=20has=20a=20string=20index=20signatu?= =?UTF-8?q?re=20of=20a=20union=20type=20of=20the=20types=20of=20the=20stri?= =?UTF-8?q?ng=20index=20signatures=20from=20each=20type=20in=20U.=20?= =?UTF-8?q?=E2=80=A2=09If=20each=20type=20in=20U=20has=20a=20numeric=20ind?= =?UTF-8?q?ex=20signature,=20U=20has=20a=20numeric=20index=20signature=20o?= =?UTF-8?q?f=20a=20union=20type=20of=20the=20types=20of=20the=20numeric=20?= =?UTF-8?q?index=20signatures=20from=20each=20type=20in=20U.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../reference/unionTypeIndexSignature.js | 44 ++++++++++ .../reference/unionTypeIndexSignature.types | 81 +++++++++++++++++++ .../types/union/unionTypeIndexSignature.ts | 23 ++++++ 3 files changed, 148 insertions(+) create mode 100644 tests/baselines/reference/unionTypeIndexSignature.js create mode 100644 tests/baselines/reference/unionTypeIndexSignature.types create mode 100644 tests/cases/conformance/types/union/unionTypeIndexSignature.ts diff --git a/tests/baselines/reference/unionTypeIndexSignature.js b/tests/baselines/reference/unionTypeIndexSignature.js new file mode 100644 index 00000000000..b39a42e76a4 --- /dev/null +++ b/tests/baselines/reference/unionTypeIndexSignature.js @@ -0,0 +1,44 @@ +//// [unionTypeIndexSignature.ts] +var numOrDate: number | Date; +var anyVar: number; + +// If each type in U has a string index signature, +// U has a string index signature of a union type of the types of the string index signatures from each type in U. + +var unionOfDifferentReturnType: { [a: string]: number; } | { [a: string]: Date; }; +numOrDate = unionOfDifferentReturnType["hello"]; // number | Date +numOrDate = unionOfDifferentReturnType[10]; // number | Date + +var unionOfTypesWithAndWithoutStringSignature: { [a: string]: number; } | boolean; +anyVar = unionOfTypesWithAndWithoutStringSignature["hello"]; // any +anyVar = unionOfTypesWithAndWithoutStringSignature[10]; // any + +// If each type in U has a numeric index signature, +// U has a numeric index signature of a union type of the types of the numeric index signatures from each type in U. +var unionOfDifferentReturnType1: { [a: number]: number; } | { [a: number]: Date; }; +numOrDate = unionOfDifferentReturnType1["hello"]; // any +numOrDate = unionOfDifferentReturnType1[10]; // number | Date + +var unionOfTypesWithAndWithoutStringSignature1: { [a: number]: number; } | boolean; +anyVar = unionOfTypesWithAndWithoutStringSignature1["hello"]; // any +anyVar = unionOfTypesWithAndWithoutStringSignature1[10]; // any + +//// [unionTypeIndexSignature.js] +var numOrDate; +var anyVar; +// If each type in U has a string index signature, +// U has a string index signature of a union type of the types of the string index signatures from each type in U. +var unionOfDifferentReturnType; +numOrDate = unionOfDifferentReturnType["hello"]; // number | Date +numOrDate = unionOfDifferentReturnType[10]; // number | Date +var unionOfTypesWithAndWithoutStringSignature; +anyVar = unionOfTypesWithAndWithoutStringSignature["hello"]; // any +anyVar = unionOfTypesWithAndWithoutStringSignature[10]; // any +// If each type in U has a numeric index signature, +// U has a numeric index signature of a union type of the types of the numeric index signatures from each type in U. +var unionOfDifferentReturnType1; +numOrDate = unionOfDifferentReturnType1["hello"]; // any +numOrDate = unionOfDifferentReturnType1[10]; // number | Date +var unionOfTypesWithAndWithoutStringSignature1; +anyVar = unionOfTypesWithAndWithoutStringSignature1["hello"]; // any +anyVar = unionOfTypesWithAndWithoutStringSignature1[10]; // any diff --git a/tests/baselines/reference/unionTypeIndexSignature.types b/tests/baselines/reference/unionTypeIndexSignature.types new file mode 100644 index 00000000000..96453cffcb4 --- /dev/null +++ b/tests/baselines/reference/unionTypeIndexSignature.types @@ -0,0 +1,81 @@ +=== tests/cases/conformance/types/union/unionTypeIndexSignature.ts === +var numOrDate: number | Date; +>numOrDate : number | Date +>Date : Date + +var anyVar: number; +>anyVar : number + +// If each type in U has a string index signature, +// U has a string index signature of a union type of the types of the string index signatures from each type in U. + +var unionOfDifferentReturnType: { [a: string]: number; } | { [a: string]: Date; }; +>unionOfDifferentReturnType : { [x: string]: number; } | { [x: string]: Date; } +>a : string +>a : string +>Date : Date + +numOrDate = unionOfDifferentReturnType["hello"]; // number | Date +>numOrDate = unionOfDifferentReturnType["hello"] : number | Date +>numOrDate : number | Date +>unionOfDifferentReturnType["hello"] : number | Date +>unionOfDifferentReturnType : { [x: string]: number; } | { [x: string]: Date; } + +numOrDate = unionOfDifferentReturnType[10]; // number | Date +>numOrDate = unionOfDifferentReturnType[10] : number | Date +>numOrDate : number | Date +>unionOfDifferentReturnType[10] : number | Date +>unionOfDifferentReturnType : { [x: string]: number; } | { [x: string]: Date; } + +var unionOfTypesWithAndWithoutStringSignature: { [a: string]: number; } | boolean; +>unionOfTypesWithAndWithoutStringSignature : boolean | { [x: string]: number; } +>a : string + +anyVar = unionOfTypesWithAndWithoutStringSignature["hello"]; // any +>anyVar = unionOfTypesWithAndWithoutStringSignature["hello"] : any +>anyVar : number +>unionOfTypesWithAndWithoutStringSignature["hello"] : any +>unionOfTypesWithAndWithoutStringSignature : boolean | { [x: string]: number; } + +anyVar = unionOfTypesWithAndWithoutStringSignature[10]; // any +>anyVar = unionOfTypesWithAndWithoutStringSignature[10] : any +>anyVar : number +>unionOfTypesWithAndWithoutStringSignature[10] : any +>unionOfTypesWithAndWithoutStringSignature : boolean | { [x: string]: number; } + +// If each type in U has a numeric index signature, +// U has a numeric index signature of a union type of the types of the numeric index signatures from each type in U. +var unionOfDifferentReturnType1: { [a: number]: number; } | { [a: number]: Date; }; +>unionOfDifferentReturnType1 : { [x: number]: number; } | { [x: number]: Date; } +>a : number +>a : number +>Date : Date + +numOrDate = unionOfDifferentReturnType1["hello"]; // any +>numOrDate = unionOfDifferentReturnType1["hello"] : any +>numOrDate : number | Date +>unionOfDifferentReturnType1["hello"] : any +>unionOfDifferentReturnType1 : { [x: number]: number; } | { [x: number]: Date; } + +numOrDate = unionOfDifferentReturnType1[10]; // number | Date +>numOrDate = unionOfDifferentReturnType1[10] : number | Date +>numOrDate : number | Date +>unionOfDifferentReturnType1[10] : number | Date +>unionOfDifferentReturnType1 : { [x: number]: number; } | { [x: number]: Date; } + +var unionOfTypesWithAndWithoutStringSignature1: { [a: number]: number; } | boolean; +>unionOfTypesWithAndWithoutStringSignature1 : boolean | { [x: number]: number; } +>a : number + +anyVar = unionOfTypesWithAndWithoutStringSignature1["hello"]; // any +>anyVar = unionOfTypesWithAndWithoutStringSignature1["hello"] : any +>anyVar : number +>unionOfTypesWithAndWithoutStringSignature1["hello"] : any +>unionOfTypesWithAndWithoutStringSignature1 : boolean | { [x: number]: number; } + +anyVar = unionOfTypesWithAndWithoutStringSignature1[10]; // any +>anyVar = unionOfTypesWithAndWithoutStringSignature1[10] : any +>anyVar : number +>unionOfTypesWithAndWithoutStringSignature1[10] : any +>unionOfTypesWithAndWithoutStringSignature1 : boolean | { [x: number]: number; } + diff --git a/tests/cases/conformance/types/union/unionTypeIndexSignature.ts b/tests/cases/conformance/types/union/unionTypeIndexSignature.ts new file mode 100644 index 00000000000..698da7449f4 --- /dev/null +++ b/tests/cases/conformance/types/union/unionTypeIndexSignature.ts @@ -0,0 +1,23 @@ +var numOrDate: number | Date; +var anyVar: number; + +// If each type in U has a string index signature, +// U has a string index signature of a union type of the types of the string index signatures from each type in U. + +var unionOfDifferentReturnType: { [a: string]: number; } | { [a: string]: Date; }; +numOrDate = unionOfDifferentReturnType["hello"]; // number | Date +numOrDate = unionOfDifferentReturnType[10]; // number | Date + +var unionOfTypesWithAndWithoutStringSignature: { [a: string]: number; } | boolean; +anyVar = unionOfTypesWithAndWithoutStringSignature["hello"]; // any +anyVar = unionOfTypesWithAndWithoutStringSignature[10]; // any + +// If each type in U has a numeric index signature, +// U has a numeric index signature of a union type of the types of the numeric index signatures from each type in U. +var unionOfDifferentReturnType1: { [a: number]: number; } | { [a: number]: Date; }; +numOrDate = unionOfDifferentReturnType1["hello"]; // any +numOrDate = unionOfDifferentReturnType1[10]; // number | Date + +var unionOfTypesWithAndWithoutStringSignature1: { [a: number]: number; } | boolean; +anyVar = unionOfTypesWithAndWithoutStringSignature1["hello"]; // any +anyVar = unionOfTypesWithAndWithoutStringSignature1[10]; // any \ No newline at end of file From b66cd9b0fc9d69d82c2142fdc14e2352e560a499 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 3 Nov 2014 15:59:57 -0800 Subject: [PATCH 10/15] Results of || operation produces union type --- .../logicalOrOperatorWithEveryType.js | 160 +++++++++--------- .../logicalOrOperatorWithEveryType.types | 80 ++++----- .../logicalOrOperatorWithEveryType.ts | 80 ++++----- 3 files changed, 160 insertions(+), 160 deletions(-) diff --git a/tests/baselines/reference/logicalOrOperatorWithEveryType.js b/tests/baselines/reference/logicalOrOperatorWithEveryType.js index bf7a641882e..78601374c22 100644 --- a/tests/baselines/reference/logicalOrOperatorWithEveryType.js +++ b/tests/baselines/reference/logicalOrOperatorWithEveryType.js @@ -28,77 +28,77 @@ var ra10 = undefined || a1; // undefined || any is any var rb1 = a1 || a2; // any || boolean is any var rb2 = a2 || a2; // boolean || boolean is boolean -var rb3 = a3 || a2; // number || boolean is {} -var rb4 = a4 || a2; // string || boolean is {} -var rb5 = a5 || a2; // void || boolean is {} -var rb6 = a6 || a2; // enum || boolean is {} -var rb7 = a7 || a2; // object || boolean is {} -var rb8 = a8 || a2; // array || boolean is {} +var rb3 = a3 || a2; // number || boolean is number | boolean +var rb4 = a4 || a2; // string || boolean is string | boolean +var rb5 = a5 || a2; // void || boolean is void | boolean +var rb6 = a6 || a2; // enum || boolean is E | boolean +var rb7 = a7 || a2; // object || boolean is object | boolean +var rb8 = a8 || a2; // array || boolean is array | boolean var rb9 = null || a2; // null || boolean is boolean var rb10= undefined || a2; // undefined || boolean is boolean var rc1 = a1 || a3; // any || number is any -var rc2 = a2 || a3; // boolean || number is {} +var rc2 = a2 || a3; // boolean || number is boolean | number var rc3 = a3 || a3; // number || number is number -var rc4 = a4 || a3; // string || number is {} -var rc5 = a5 || a3; // void || number is {} +var rc4 = a4 || a3; // string || number is string | number +var rc5 = a5 || a3; // void || number is void | number var rc6 = a6 || a3; // enum || number is number -var rc7 = a7 || a3; // object || number is {} -var rc8 = a8 || a3; // array || number is {} +var rc7 = a7 || a3; // object || number is object | number +var rc8 = a8 || a3; // array || number is array | number var rc9 = null || a3; // null || number is number var rc10 = undefined || a3; // undefined || number is number var rd1 = a1 || a4; // any || string is any -var rd2 = a2 || a4; // boolean || string is {} -var rd3 = a3 || a4; // number || string is {} +var rd2 = a2 || a4; // boolean || string is boolean | string +var rd3 = a3 || a4; // number || string is number | string var rd4 = a4 || a4; // string || string is string -var rd5 = a5 || a4; // void || string is {} -var rd6 = a6 || a4; // enum || string is {} -var rd7 = a7 || a4; // object || string is {} -var rd8 = a8 || a4; // array || string is {} +var rd5 = a5 || a4; // void || string is void | string +var rd6 = a6 || a4; // enum || string is enum | string +var rd7 = a7 || a4; // object || string is object | string +var rd8 = a8 || a4; // array || string is array | string var rd9 = null || a4; // null || string is string var rd10 = undefined || a4; // undefined || string is string var re1 = a1 || a5; // any || void is any -var re2 = a2 || a5; // boolean || void is {} -var re3 = a3 || a5; // number || void is {} -var re4 = a4 || a5; // string || void is {} +var re2 = a2 || a5; // boolean || void is boolean | void +var re3 = a3 || a5; // number || void is number | void +var re4 = a4 || a5; // string || void is string | void var re5 = a5 || a5; // void || void is void -var re6 = a6 || a5; // enum || void is {} -var re7 = a7 || a5; // object || void is {} -var re8 = a8 || a5; // array || void is {} +var re6 = a6 || a5; // enum || void is enum | void +var re7 = a7 || a5; // object || void is object | void +var re8 = a8 || a5; // array || void is array | void var re9 = null || a5; // null || void is void var re10 = undefined || a5; // undefined || void is void var rg1 = a1 || a6; // any || enum is any -var rg2 = a2 || a6; // boolean || enum is {} +var rg2 = a2 || a6; // boolean || enum is boolean | enum var rg3 = a3 || a6; // number || enum is number -var rg4 = a4 || a6; // string || enum is {} -var rg5 = a5 || a6; // void || enum is {} +var rg4 = a4 || a6; // string || enum is string | enum +var rg5 = a5 || a6; // void || enum is void | enum var rg6 = a6 || a6; // enum || enum is E -var rg7 = a7 || a6; // object || enum is {} -var rg8 = a8 || a6; // array || enum is {} +var rg7 = a7 || a6; // object || enum is object | enum +var rg8 = a8 || a6; // array || enum is array | enum var rg9 = null || a6; // null || enum is E var rg10 = undefined || a6; // undefined || enum is E var rh1 = a1 || a7; // any || object is any -var rh2 = a2 || a7; // boolean || object is {} -var rh3 = a3 || a7; // number || object is {} -var rh4 = a4 || a7; // string || object is {} -var rh5 = a5 || a7; // void || object is {} -var rh6 = a6 || a7; // enum || object is {} +var rh2 = a2 || a7; // boolean || object is boolean | object +var rh3 = a3 || a7; // number || object is number | object +var rh4 = a4 || a7; // string || object is string | object +var rh5 = a5 || a7; // void || object is void | object +var rh6 = a6 || a7; // enum || object is enum | object var rh7 = a7 || a7; // object || object is object -var rh8 = a8 || a7; // array || object is {} +var rh8 = a8 || a7; // array || object is array | object var rh9 = null || a7; // null || object is object var rh10 = undefined || a7; // undefined || object is object var ri1 = a1 || a8; // any || array is any -var ri2 = a2 || a8; // boolean || array is {} -var ri3 = a3 || a8; // number || array is {} -var ri4 = a4 || a8; // string || array is {} -var ri5 = a5 || a8; // void || array is {} -var ri6 = a6 || a8; // enum || array is {} -var ri7 = a7 || a8; // object || array is {} +var ri2 = a2 || a8; // boolean || array is boolean | array +var ri3 = a3 || a8; // number || array is number | array +var ri4 = a4 || a8; // string || array is string | array +var ri5 = a5 || a8; // void || array is void | array +var ri6 = a6 || a8; // enum || array is enum | array +var ri7 = a7 || a8; // object || array is object | array var ri8 = a8 || a8; // array || array is array var ri9 = null || a8; // null || array is array var ri10 = undefined || a8; // undefined || array is array @@ -156,71 +156,71 @@ var ra9 = null || a1; // null || any is any var ra10 = undefined || a1; // undefined || any is any var rb1 = a1 || a2; // any || boolean is any var rb2 = a2 || a2; // boolean || boolean is boolean -var rb3 = a3 || a2; // number || boolean is {} -var rb4 = a4 || a2; // string || boolean is {} -var rb5 = a5 || a2; // void || boolean is {} -var rb6 = a6 || a2; // enum || boolean is {} -var rb7 = a7 || a2; // object || boolean is {} -var rb8 = a8 || a2; // array || boolean is {} +var rb3 = a3 || a2; // number || boolean is number | boolean +var rb4 = a4 || a2; // string || boolean is string | boolean +var rb5 = a5 || a2; // void || boolean is void | boolean +var rb6 = a6 || a2; // enum || boolean is E | boolean +var rb7 = a7 || a2; // object || boolean is object | boolean +var rb8 = a8 || a2; // array || boolean is array | boolean var rb9 = null || a2; // null || boolean is boolean var rb10 = undefined || a2; // undefined || boolean is boolean var rc1 = a1 || a3; // any || number is any -var rc2 = a2 || a3; // boolean || number is {} +var rc2 = a2 || a3; // boolean || number is boolean | number var rc3 = a3 || a3; // number || number is number -var rc4 = a4 || a3; // string || number is {} -var rc5 = a5 || a3; // void || number is {} +var rc4 = a4 || a3; // string || number is string | number +var rc5 = a5 || a3; // void || number is void | number var rc6 = a6 || a3; // enum || number is number -var rc7 = a7 || a3; // object || number is {} -var rc8 = a8 || a3; // array || number is {} +var rc7 = a7 || a3; // object || number is object | number +var rc8 = a8 || a3; // array || number is array | number var rc9 = null || a3; // null || number is number var rc10 = undefined || a3; // undefined || number is number var rd1 = a1 || a4; // any || string is any -var rd2 = a2 || a4; // boolean || string is {} -var rd3 = a3 || a4; // number || string is {} +var rd2 = a2 || a4; // boolean || string is boolean | string +var rd3 = a3 || a4; // number || string is number | string var rd4 = a4 || a4; // string || string is string -var rd5 = a5 || a4; // void || string is {} -var rd6 = a6 || a4; // enum || string is {} -var rd7 = a7 || a4; // object || string is {} -var rd8 = a8 || a4; // array || string is {} +var rd5 = a5 || a4; // void || string is void | string +var rd6 = a6 || a4; // enum || string is enum | string +var rd7 = a7 || a4; // object || string is object | string +var rd8 = a8 || a4; // array || string is array | string var rd9 = null || a4; // null || string is string var rd10 = undefined || a4; // undefined || string is string var re1 = a1 || a5; // any || void is any -var re2 = a2 || a5; // boolean || void is {} -var re3 = a3 || a5; // number || void is {} -var re4 = a4 || a5; // string || void is {} +var re2 = a2 || a5; // boolean || void is boolean | void +var re3 = a3 || a5; // number || void is number | void +var re4 = a4 || a5; // string || void is string | void var re5 = a5 || a5; // void || void is void -var re6 = a6 || a5; // enum || void is {} -var re7 = a7 || a5; // object || void is {} -var re8 = a8 || a5; // array || void is {} +var re6 = a6 || a5; // enum || void is enum | void +var re7 = a7 || a5; // object || void is object | void +var re8 = a8 || a5; // array || void is array | void var re9 = null || a5; // null || void is void var re10 = undefined || a5; // undefined || void is void var rg1 = a1 || a6; // any || enum is any -var rg2 = a2 || a6; // boolean || enum is {} +var rg2 = a2 || a6; // boolean || enum is boolean | enum var rg3 = a3 || a6; // number || enum is number -var rg4 = a4 || a6; // string || enum is {} -var rg5 = a5 || a6; // void || enum is {} +var rg4 = a4 || a6; // string || enum is string | enum +var rg5 = a5 || a6; // void || enum is void | enum var rg6 = a6 || a6; // enum || enum is E -var rg7 = a7 || a6; // object || enum is {} -var rg8 = a8 || a6; // array || enum is {} +var rg7 = a7 || a6; // object || enum is object | enum +var rg8 = a8 || a6; // array || enum is array | enum var rg9 = null || a6; // null || enum is E var rg10 = undefined || a6; // undefined || enum is E var rh1 = a1 || a7; // any || object is any -var rh2 = a2 || a7; // boolean || object is {} -var rh3 = a3 || a7; // number || object is {} -var rh4 = a4 || a7; // string || object is {} -var rh5 = a5 || a7; // void || object is {} -var rh6 = a6 || a7; // enum || object is {} +var rh2 = a2 || a7; // boolean || object is boolean | object +var rh3 = a3 || a7; // number || object is number | object +var rh4 = a4 || a7; // string || object is string | object +var rh5 = a5 || a7; // void || object is void | object +var rh6 = a6 || a7; // enum || object is enum | object var rh7 = a7 || a7; // object || object is object -var rh8 = a8 || a7; // array || object is {} +var rh8 = a8 || a7; // array || object is array | object var rh9 = null || a7; // null || object is object var rh10 = undefined || a7; // undefined || object is object var ri1 = a1 || a8; // any || array is any -var ri2 = a2 || a8; // boolean || array is {} -var ri3 = a3 || a8; // number || array is {} -var ri4 = a4 || a8; // string || array is {} -var ri5 = a5 || a8; // void || array is {} -var ri6 = a6 || a8; // enum || array is {} -var ri7 = a7 || a8; // object || array is {} +var ri2 = a2 || a8; // boolean || array is boolean | array +var ri3 = a3 || a8; // number || array is number | array +var ri4 = a4 || a8; // string || array is string | array +var ri5 = a5 || a8; // void || array is void | array +var ri6 = a6 || a8; // enum || array is enum | array +var ri7 = a7 || a8; // object || array is object | array var ri8 = a8 || a8; // array || array is array var ri9 = null || a8; // null || array is array var ri10 = undefined || a8; // undefined || array is array diff --git a/tests/baselines/reference/logicalOrOperatorWithEveryType.types b/tests/baselines/reference/logicalOrOperatorWithEveryType.types index 3e3b0dcf37f..ae8dab8c71c 100644 --- a/tests/baselines/reference/logicalOrOperatorWithEveryType.types +++ b/tests/baselines/reference/logicalOrOperatorWithEveryType.types @@ -107,37 +107,37 @@ var rb2 = a2 || a2; // boolean || boolean is boolean >a2 : boolean >a2 : boolean -var rb3 = a3 || a2; // number || boolean is {} +var rb3 = a3 || a2; // number || boolean is number | boolean >rb3 : number | boolean >a3 || a2 : number | boolean >a3 : number >a2 : boolean -var rb4 = a4 || a2; // string || boolean is {} +var rb4 = a4 || a2; // string || boolean is string | boolean >rb4 : string | boolean >a4 || a2 : string | boolean >a4 : string >a2 : boolean -var rb5 = a5 || a2; // void || boolean is {} +var rb5 = a5 || a2; // void || boolean is void | boolean >rb5 : boolean | void >a5 || a2 : boolean | void >a5 : void >a2 : boolean -var rb6 = a6 || a2; // enum || boolean is {} +var rb6 = a6 || a2; // enum || boolean is E | boolean >rb6 : boolean | E >a6 || a2 : boolean | E >a6 : E >a2 : boolean -var rb7 = a7 || a2; // object || boolean is {} +var rb7 = a7 || a2; // object || boolean is object | boolean >rb7 : boolean | { a: string; } >a7 || a2 : boolean | { a: string; } >a7 : { a: string; } >a2 : boolean -var rb8 = a8 || a2; // array || boolean is {} +var rb8 = a8 || a2; // array || boolean is array | boolean >rb8 : boolean | string[] >a8 || a2 : boolean | string[] >a8 : string[] @@ -160,7 +160,7 @@ var rc1 = a1 || a3; // any || number is any >a1 : any >a3 : number -var rc2 = a2 || a3; // boolean || number is {} +var rc2 = a2 || a3; // boolean || number is boolean | number >rc2 : number | boolean >a2 || a3 : number | boolean >a2 : boolean @@ -172,13 +172,13 @@ var rc3 = a3 || a3; // number || number is number >a3 : number >a3 : number -var rc4 = a4 || a3; // string || number is {} +var rc4 = a4 || a3; // string || number is string | number >rc4 : string | number >a4 || a3 : string | number >a4 : string >a3 : number -var rc5 = a5 || a3; // void || number is {} +var rc5 = a5 || a3; // void || number is void | number >rc5 : number | void >a5 || a3 : number | void >a5 : void @@ -190,13 +190,13 @@ var rc6 = a6 || a3; // enum || number is number >a6 : E >a3 : number -var rc7 = a7 || a3; // object || number is {} +var rc7 = a7 || a3; // object || number is object | number >rc7 : number | { a: string; } >a7 || a3 : number | { a: string; } >a7 : { a: string; } >a3 : number -var rc8 = a8 || a3; // array || number is {} +var rc8 = a8 || a3; // array || number is array | number >rc8 : number | string[] >a8 || a3 : number | string[] >a8 : string[] @@ -219,13 +219,13 @@ var rd1 = a1 || a4; // any || string is any >a1 : any >a4 : string -var rd2 = a2 || a4; // boolean || string is {} +var rd2 = a2 || a4; // boolean || string is boolean | string >rd2 : string | boolean >a2 || a4 : string | boolean >a2 : boolean >a4 : string -var rd3 = a3 || a4; // number || string is {} +var rd3 = a3 || a4; // number || string is number | string >rd3 : string | number >a3 || a4 : string | number >a3 : number @@ -237,25 +237,25 @@ var rd4 = a4 || a4; // string || string is string >a4 : string >a4 : string -var rd5 = a5 || a4; // void || string is {} +var rd5 = a5 || a4; // void || string is void | string >rd5 : string | void >a5 || a4 : string | void >a5 : void >a4 : string -var rd6 = a6 || a4; // enum || string is {} +var rd6 = a6 || a4; // enum || string is enum | string >rd6 : string | E >a6 || a4 : string | E >a6 : E >a4 : string -var rd7 = a7 || a4; // object || string is {} +var rd7 = a7 || a4; // object || string is object | string >rd7 : string | { a: string; } >a7 || a4 : string | { a: string; } >a7 : { a: string; } >a4 : string -var rd8 = a8 || a4; // array || string is {} +var rd8 = a8 || a4; // array || string is array | string >rd8 : string | string[] >a8 || a4 : string | string[] >a8 : string[] @@ -278,19 +278,19 @@ var re1 = a1 || a5; // any || void is any >a1 : any >a5 : void -var re2 = a2 || a5; // boolean || void is {} +var re2 = a2 || a5; // boolean || void is boolean | void >re2 : boolean | void >a2 || a5 : boolean | void >a2 : boolean >a5 : void -var re3 = a3 || a5; // number || void is {} +var re3 = a3 || a5; // number || void is number | void >re3 : number | void >a3 || a5 : number | void >a3 : number >a5 : void -var re4 = a4 || a5; // string || void is {} +var re4 = a4 || a5; // string || void is string | void >re4 : string | void >a4 || a5 : string | void >a4 : string @@ -302,19 +302,19 @@ var re5 = a5 || a5; // void || void is void >a5 : void >a5 : void -var re6 = a6 || a5; // enum || void is {} +var re6 = a6 || a5; // enum || void is enum | void >re6 : void | E >a6 || a5 : void | E >a6 : E >a5 : void -var re7 = a7 || a5; // object || void is {} +var re7 = a7 || a5; // object || void is object | void >re7 : void | { a: string; } >a7 || a5 : void | { a: string; } >a7 : { a: string; } >a5 : void -var re8 = a8 || a5; // array || void is {} +var re8 = a8 || a5; // array || void is array | void >re8 : void | string[] >a8 || a5 : void | string[] >a8 : string[] @@ -337,7 +337,7 @@ var rg1 = a1 || a6; // any || enum is any >a1 : any >a6 : E -var rg2 = a2 || a6; // boolean || enum is {} +var rg2 = a2 || a6; // boolean || enum is boolean | enum >rg2 : boolean | E >a2 || a6 : boolean | E >a2 : boolean @@ -349,13 +349,13 @@ var rg3 = a3 || a6; // number || enum is number >a3 : number >a6 : E -var rg4 = a4 || a6; // string || enum is {} +var rg4 = a4 || a6; // string || enum is string | enum >rg4 : string | E >a4 || a6 : string | E >a4 : string >a6 : E -var rg5 = a5 || a6; // void || enum is {} +var rg5 = a5 || a6; // void || enum is void | enum >rg5 : void | E >a5 || a6 : void | E >a5 : void @@ -367,13 +367,13 @@ var rg6 = a6 || a6; // enum || enum is E >a6 : E >a6 : E -var rg7 = a7 || a6; // object || enum is {} +var rg7 = a7 || a6; // object || enum is object | enum >rg7 : E | { a: string; } >a7 || a6 : E | { a: string; } >a7 : { a: string; } >a6 : E -var rg8 = a8 || a6; // array || enum is {} +var rg8 = a8 || a6; // array || enum is array | enum >rg8 : string[] | E >a8 || a6 : string[] | E >a8 : string[] @@ -396,31 +396,31 @@ var rh1 = a1 || a7; // any || object is any >a1 : any >a7 : { a: string; } -var rh2 = a2 || a7; // boolean || object is {} +var rh2 = a2 || a7; // boolean || object is boolean | object >rh2 : boolean | { a: string; } >a2 || a7 : boolean | { a: string; } >a2 : boolean >a7 : { a: string; } -var rh3 = a3 || a7; // number || object is {} +var rh3 = a3 || a7; // number || object is number | object >rh3 : number | { a: string; } >a3 || a7 : number | { a: string; } >a3 : number >a7 : { a: string; } -var rh4 = a4 || a7; // string || object is {} +var rh4 = a4 || a7; // string || object is string | object >rh4 : string | { a: string; } >a4 || a7 : string | { a: string; } >a4 : string >a7 : { a: string; } -var rh5 = a5 || a7; // void || object is {} +var rh5 = a5 || a7; // void || object is void | object >rh5 : void | { a: string; } >a5 || a7 : void | { a: string; } >a5 : void >a7 : { a: string; } -var rh6 = a6 || a7; // enum || object is {} +var rh6 = a6 || a7; // enum || object is enum | object >rh6 : E | { a: string; } >a6 || a7 : E | { a: string; } >a6 : E @@ -432,7 +432,7 @@ var rh7 = a7 || a7; // object || object is object >a7 : { a: string; } >a7 : { a: string; } -var rh8 = a8 || a7; // array || object is {} +var rh8 = a8 || a7; // array || object is array | object >rh8 : string[] | { a: string; } >a8 || a7 : string[] | { a: string; } >a8 : string[] @@ -455,37 +455,37 @@ var ri1 = a1 || a8; // any || array is any >a1 : any >a8 : string[] -var ri2 = a2 || a8; // boolean || array is {} +var ri2 = a2 || a8; // boolean || array is boolean | array >ri2 : boolean | string[] >a2 || a8 : boolean | string[] >a2 : boolean >a8 : string[] -var ri3 = a3 || a8; // number || array is {} +var ri3 = a3 || a8; // number || array is number | array >ri3 : number | string[] >a3 || a8 : number | string[] >a3 : number >a8 : string[] -var ri4 = a4 || a8; // string || array is {} +var ri4 = a4 || a8; // string || array is string | array >ri4 : string | string[] >a4 || a8 : string | string[] >a4 : string >a8 : string[] -var ri5 = a5 || a8; // void || array is {} +var ri5 = a5 || a8; // void || array is void | array >ri5 : void | string[] >a5 || a8 : void | string[] >a5 : void >a8 : string[] -var ri6 = a6 || a8; // enum || array is {} +var ri6 = a6 || a8; // enum || array is enum | array >ri6 : string[] | E >a6 || a8 : string[] | E >a6 : E >a8 : string[] -var ri7 = a7 || a8; // object || array is {} +var ri7 = a7 || a8; // object || array is object | array >ri7 : string[] | { a: string; } >a7 || a8 : string[] | { a: string; } >a7 : { a: string; } diff --git a/tests/cases/conformance/expressions/binaryOperators/logicalOrOperator/logicalOrOperatorWithEveryType.ts b/tests/cases/conformance/expressions/binaryOperators/logicalOrOperator/logicalOrOperatorWithEveryType.ts index 2db2b854f6a..9ec124449f3 100644 --- a/tests/cases/conformance/expressions/binaryOperators/logicalOrOperator/logicalOrOperatorWithEveryType.ts +++ b/tests/cases/conformance/expressions/binaryOperators/logicalOrOperator/logicalOrOperatorWithEveryType.ts @@ -27,77 +27,77 @@ var ra10 = undefined || a1; // undefined || any is any var rb1 = a1 || a2; // any || boolean is any var rb2 = a2 || a2; // boolean || boolean is boolean -var rb3 = a3 || a2; // number || boolean is {} -var rb4 = a4 || a2; // string || boolean is {} -var rb5 = a5 || a2; // void || boolean is {} -var rb6 = a6 || a2; // enum || boolean is {} -var rb7 = a7 || a2; // object || boolean is {} -var rb8 = a8 || a2; // array || boolean is {} +var rb3 = a3 || a2; // number || boolean is number | boolean +var rb4 = a4 || a2; // string || boolean is string | boolean +var rb5 = a5 || a2; // void || boolean is void | boolean +var rb6 = a6 || a2; // enum || boolean is E | boolean +var rb7 = a7 || a2; // object || boolean is object | boolean +var rb8 = a8 || a2; // array || boolean is array | boolean var rb9 = null || a2; // null || boolean is boolean var rb10= undefined || a2; // undefined || boolean is boolean var rc1 = a1 || a3; // any || number is any -var rc2 = a2 || a3; // boolean || number is {} +var rc2 = a2 || a3; // boolean || number is boolean | number var rc3 = a3 || a3; // number || number is number -var rc4 = a4 || a3; // string || number is {} -var rc5 = a5 || a3; // void || number is {} +var rc4 = a4 || a3; // string || number is string | number +var rc5 = a5 || a3; // void || number is void | number var rc6 = a6 || a3; // enum || number is number -var rc7 = a7 || a3; // object || number is {} -var rc8 = a8 || a3; // array || number is {} +var rc7 = a7 || a3; // object || number is object | number +var rc8 = a8 || a3; // array || number is array | number var rc9 = null || a3; // null || number is number var rc10 = undefined || a3; // undefined || number is number var rd1 = a1 || a4; // any || string is any -var rd2 = a2 || a4; // boolean || string is {} -var rd3 = a3 || a4; // number || string is {} +var rd2 = a2 || a4; // boolean || string is boolean | string +var rd3 = a3 || a4; // number || string is number | string var rd4 = a4 || a4; // string || string is string -var rd5 = a5 || a4; // void || string is {} -var rd6 = a6 || a4; // enum || string is {} -var rd7 = a7 || a4; // object || string is {} -var rd8 = a8 || a4; // array || string is {} +var rd5 = a5 || a4; // void || string is void | string +var rd6 = a6 || a4; // enum || string is enum | string +var rd7 = a7 || a4; // object || string is object | string +var rd8 = a8 || a4; // array || string is array | string var rd9 = null || a4; // null || string is string var rd10 = undefined || a4; // undefined || string is string var re1 = a1 || a5; // any || void is any -var re2 = a2 || a5; // boolean || void is {} -var re3 = a3 || a5; // number || void is {} -var re4 = a4 || a5; // string || void is {} +var re2 = a2 || a5; // boolean || void is boolean | void +var re3 = a3 || a5; // number || void is number | void +var re4 = a4 || a5; // string || void is string | void var re5 = a5 || a5; // void || void is void -var re6 = a6 || a5; // enum || void is {} -var re7 = a7 || a5; // object || void is {} -var re8 = a8 || a5; // array || void is {} +var re6 = a6 || a5; // enum || void is enum | void +var re7 = a7 || a5; // object || void is object | void +var re8 = a8 || a5; // array || void is array | void var re9 = null || a5; // null || void is void var re10 = undefined || a5; // undefined || void is void var rg1 = a1 || a6; // any || enum is any -var rg2 = a2 || a6; // boolean || enum is {} +var rg2 = a2 || a6; // boolean || enum is boolean | enum var rg3 = a3 || a6; // number || enum is number -var rg4 = a4 || a6; // string || enum is {} -var rg5 = a5 || a6; // void || enum is {} +var rg4 = a4 || a6; // string || enum is string | enum +var rg5 = a5 || a6; // void || enum is void | enum var rg6 = a6 || a6; // enum || enum is E -var rg7 = a7 || a6; // object || enum is {} -var rg8 = a8 || a6; // array || enum is {} +var rg7 = a7 || a6; // object || enum is object | enum +var rg8 = a8 || a6; // array || enum is array | enum var rg9 = null || a6; // null || enum is E var rg10 = undefined || a6; // undefined || enum is E var rh1 = a1 || a7; // any || object is any -var rh2 = a2 || a7; // boolean || object is {} -var rh3 = a3 || a7; // number || object is {} -var rh4 = a4 || a7; // string || object is {} -var rh5 = a5 || a7; // void || object is {} -var rh6 = a6 || a7; // enum || object is {} +var rh2 = a2 || a7; // boolean || object is boolean | object +var rh3 = a3 || a7; // number || object is number | object +var rh4 = a4 || a7; // string || object is string | object +var rh5 = a5 || a7; // void || object is void | object +var rh6 = a6 || a7; // enum || object is enum | object var rh7 = a7 || a7; // object || object is object -var rh8 = a8 || a7; // array || object is {} +var rh8 = a8 || a7; // array || object is array | object var rh9 = null || a7; // null || object is object var rh10 = undefined || a7; // undefined || object is object var ri1 = a1 || a8; // any || array is any -var ri2 = a2 || a8; // boolean || array is {} -var ri3 = a3 || a8; // number || array is {} -var ri4 = a4 || a8; // string || array is {} -var ri5 = a5 || a8; // void || array is {} -var ri6 = a6 || a8; // enum || array is {} -var ri7 = a7 || a8; // object || array is {} +var ri2 = a2 || a8; // boolean || array is boolean | array +var ri3 = a3 || a8; // number || array is number | array +var ri4 = a4 || a8; // string || array is string | array +var ri5 = a5 || a8; // void || array is void | array +var ri6 = a6 || a8; // enum || array is enum | array +var ri7 = a7 || a8; // object || array is object | array var ri8 = a8 || a8; // array || array is array var ri9 = null || a8; // null || array is array var ri10 = undefined || a8; // undefined || array is array From 24ebc750c007a3752d135940bebff54427d2b118 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 3 Nov 2014 16:25:09 -0800 Subject: [PATCH 11/15] Tests for Conditional operator can generate union type --- ...nditionalOperatorConditionIsBooleanType.js | 14 +++++ ...tionalOperatorConditionIsBooleanType.types | 45 ++++++++++++++ ...onditionalOperatorConditionIsNumberType.js | 13 +++- ...itionalOperatorConditionIsNumberType.types | 42 +++++++++++++ ...onditionalOperatorConditionIsObjectType.js | 12 ++++ ...itionalOperatorConditionIsObjectType.types | 49 +++++++++++++++ .../conditionalOperatorConditoinIsAnyType.js | 17 +++++- ...onditionalOperatorConditoinIsAnyType.types | 59 +++++++++++++++++++ ...onditionalOperatorConditoinIsStringType.js | 15 ++++- ...itionalOperatorConditoinIsStringType.types | 48 +++++++++++++++ ...onalOperatorWithoutIdenticalBCT.errors.txt | 11 ++-- .../conditionalOperatorWithoutIdenticalBCT.js | 7 ++- ...nditionalOperatorConditionIsBooleanType.ts | 7 +++ ...onditionalOperatorConditionIsNumberType.ts | 6 ++ ...onditionalOperatorConditionIsObjectType.ts | 6 ++ .../conditionalOperatorConditoinIsAnyType.ts | 8 +++ ...onditionalOperatorConditoinIsStringType.ts | 7 +++ .../conditionalOperatorWithoutIdenticalBCT.ts | 4 +- 18 files changed, 361 insertions(+), 9 deletions(-) diff --git a/tests/baselines/reference/conditionalOperatorConditionIsBooleanType.js b/tests/baselines/reference/conditionalOperatorConditionIsBooleanType.js index ab9dca9023f..d9a8b2daa29 100644 --- a/tests/baselines/reference/conditionalOperatorConditionIsBooleanType.js +++ b/tests/baselines/reference/conditionalOperatorConditionIsBooleanType.js @@ -20,6 +20,7 @@ condBoolean ? exprBoolean1 : exprBoolean2; condBoolean ? exprNumber1 : exprNumber2; condBoolean ? exprString1 : exprString2; condBoolean ? exprIsObject1 : exprIsObject2; +condBoolean ? exprString1 : exprBoolean1; // union //Cond is a boolean type literal true ? exprAny1 : exprAny2; @@ -27,6 +28,7 @@ false ? exprBoolean1 : exprBoolean2; true ? exprNumber1 : exprNumber2; false ? exprString1 : exprString2; true ? exprIsObject1 : exprIsObject2; +true ? exprString1 : exprBoolean1; // union //Cond is a boolean type expression !true ? exprAny1 : exprAny2; @@ -34,6 +36,7 @@ typeof "123" == "string" ? exprBoolean1 : exprBoolean2; 2 > 1 ? exprNumber1 : exprNumber2; null === undefined ? exprString1 : exprString2; true || false ? exprIsObject1 : exprIsObject2; +null === undefined ? exprString1 : exprBoolean1; // union //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condBoolean ? exprAny1 : exprAny2; @@ -41,18 +44,22 @@ var resultIsBoolean1 = condBoolean ? exprBoolean1 : exprBoolean2; var resultIsNumber1 = condBoolean ? exprNumber1 : exprNumber2; var resultIsString1 = condBoolean ? exprString1 : exprString2; var resultIsObject1 = condBoolean ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean1 = condBoolean ? exprString1 : exprBoolean1; // union var resultIsAny2 = true ? exprAny1 : exprAny2; var resultIsBoolean2 = false ? exprBoolean1 : exprBoolean2; var resultIsNumber2 = true ? exprNumber1 : exprNumber2; var resultIsString2 = false ? exprString1 : exprString2; var resultIsObject2 = true ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean2 = true ? exprString1 : exprBoolean1; // union +var resultIsStringOrBoolean3 = false ? exprString1 : exprBoolean1; // union var resultIsAny3 = !true ? exprAny1 : exprAny2; var resultIsBoolean3 = typeof "123" == "string" ? exprBoolean1 : exprBoolean2; var resultIsNumber3 = 2 > 1 ? exprNumber1 : exprNumber2; var resultIsString3 = null === undefined ? exprString1 : exprString2; var resultIsObject3 = true || false ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean4 = typeof "123" === "string" ? exprString1 : exprBoolean1; // union //// [conditionalOperatorConditionIsBooleanType.js] @@ -74,31 +81,38 @@ condBoolean ? exprBoolean1 : exprBoolean2; condBoolean ? exprNumber1 : exprNumber2; condBoolean ? exprString1 : exprString2; condBoolean ? exprIsObject1 : exprIsObject2; +condBoolean ? exprString1 : exprBoolean1; // union //Cond is a boolean type literal true ? exprAny1 : exprAny2; false ? exprBoolean1 : exprBoolean2; true ? exprNumber1 : exprNumber2; false ? exprString1 : exprString2; true ? exprIsObject1 : exprIsObject2; +true ? exprString1 : exprBoolean1; // union //Cond is a boolean type expression !true ? exprAny1 : exprAny2; typeof "123" == "string" ? exprBoolean1 : exprBoolean2; 2 > 1 ? exprNumber1 : exprNumber2; null === undefined ? exprString1 : exprString2; true || false ? exprIsObject1 : exprIsObject2; +null === undefined ? exprString1 : exprBoolean1; // union //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condBoolean ? exprAny1 : exprAny2; var resultIsBoolean1 = condBoolean ? exprBoolean1 : exprBoolean2; var resultIsNumber1 = condBoolean ? exprNumber1 : exprNumber2; var resultIsString1 = condBoolean ? exprString1 : exprString2; var resultIsObject1 = condBoolean ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean1 = condBoolean ? exprString1 : exprBoolean1; // union var resultIsAny2 = true ? exprAny1 : exprAny2; var resultIsBoolean2 = false ? exprBoolean1 : exprBoolean2; var resultIsNumber2 = true ? exprNumber1 : exprNumber2; var resultIsString2 = false ? exprString1 : exprString2; var resultIsObject2 = true ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean2 = true ? exprString1 : exprBoolean1; // union +var resultIsStringOrBoolean3 = false ? exprString1 : exprBoolean1; // union var resultIsAny3 = !true ? exprAny1 : exprAny2; var resultIsBoolean3 = typeof "123" == "string" ? exprBoolean1 : exprBoolean2; var resultIsNumber3 = 2 > 1 ? exprNumber1 : exprNumber2; var resultIsString3 = null === undefined ? exprString1 : exprString2; var resultIsObject3 = true || false ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean4 = typeof "123" === "string" ? exprString1 : exprBoolean1; // union diff --git a/tests/baselines/reference/conditionalOperatorConditionIsBooleanType.types b/tests/baselines/reference/conditionalOperatorConditionIsBooleanType.types index b3ca65219cb..44fc9f5ed7b 100644 --- a/tests/baselines/reference/conditionalOperatorConditionIsBooleanType.types +++ b/tests/baselines/reference/conditionalOperatorConditionIsBooleanType.types @@ -66,6 +66,12 @@ condBoolean ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +condBoolean ? exprString1 : exprBoolean1; // union +>condBoolean ? exprString1 : exprBoolean1 : string | boolean +>condBoolean : boolean +>exprString1 : string +>exprBoolean1 : boolean + //Cond is a boolean type literal true ? exprAny1 : exprAny2; >true ? exprAny1 : exprAny2 : any @@ -92,6 +98,11 @@ true ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +true ? exprString1 : exprBoolean1; // union +>true ? exprString1 : exprBoolean1 : string | boolean +>exprString1 : string +>exprBoolean1 : boolean + //Cond is a boolean type expression !true ? exprAny1 : exprAny2; >!true ? exprAny1 : exprAny2 : any @@ -125,6 +136,13 @@ true || false ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +null === undefined ? exprString1 : exprBoolean1; // union +>null === undefined ? exprString1 : exprBoolean1 : string | boolean +>null === undefined : boolean +>undefined : undefined +>exprString1 : string +>exprBoolean1 : boolean + //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condBoolean ? exprAny1 : exprAny2; >resultIsAny1 : any @@ -161,6 +179,13 @@ var resultIsObject1 = condBoolean ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +var resultIsStringOrBoolean1 = condBoolean ? exprString1 : exprBoolean1; // union +>resultIsStringOrBoolean1 : string | boolean +>condBoolean ? exprString1 : exprBoolean1 : string | boolean +>condBoolean : boolean +>exprString1 : string +>exprBoolean1 : boolean + var resultIsAny2 = true ? exprAny1 : exprAny2; >resultIsAny2 : any >true ? exprAny1 : exprAny2 : any @@ -191,6 +216,18 @@ var resultIsObject2 = true ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +var resultIsStringOrBoolean2 = true ? exprString1 : exprBoolean1; // union +>resultIsStringOrBoolean2 : string | boolean +>true ? exprString1 : exprBoolean1 : string | boolean +>exprString1 : string +>exprBoolean1 : boolean + +var resultIsStringOrBoolean3 = false ? exprString1 : exprBoolean1; // union +>resultIsStringOrBoolean3 : string | boolean +>false ? exprString1 : exprBoolean1 : string | boolean +>exprString1 : string +>exprBoolean1 : boolean + var resultIsAny3 = !true ? exprAny1 : exprAny2; >resultIsAny3 : any >!true ? exprAny1 : exprAny2 : any @@ -228,3 +265,11 @@ var resultIsObject3 = true || false ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +var resultIsStringOrBoolean4 = typeof "123" === "string" ? exprString1 : exprBoolean1; // union +>resultIsStringOrBoolean4 : string | boolean +>typeof "123" === "string" ? exprString1 : exprBoolean1 : string | boolean +>typeof "123" === "string" : boolean +>typeof "123" : string +>exprString1 : string +>exprBoolean1 : boolean + diff --git a/tests/baselines/reference/conditionalOperatorConditionIsNumberType.js b/tests/baselines/reference/conditionalOperatorConditionIsNumberType.js index 166841f0a89..46a04169e93 100644 --- a/tests/baselines/reference/conditionalOperatorConditionIsNumberType.js +++ b/tests/baselines/reference/conditionalOperatorConditionIsNumberType.js @@ -20,6 +20,7 @@ condNumber ? exprBoolean1 : exprBoolean2; condNumber ? exprNumber1 : exprNumber2; condNumber ? exprString1 : exprString2; condNumber ? exprIsObject1 : exprIsObject2; +condNumber ? exprString1 : exprBoolean1; // Union //Cond is a number type literal 1 ? exprAny1 : exprAny2; @@ -27,6 +28,7 @@ condNumber ? exprIsObject1 : exprIsObject2; 0.123456789 ? exprNumber1 : exprNumber2; - 10000000000000 ? exprString1 : exprString2; 1000000000000 ? exprIsObject1 : exprIsObject2; +10000 ? exprString1 : exprBoolean1; // Union //Cond is a number type expression function foo() { return 1 }; @@ -37,6 +39,7 @@ var array = [1, 2, 3]; "string".length ? exprNumber1 : exprNumber2; foo() ? exprString1 : exprString2; foo() / array[1] ? exprIsObject1 : exprIsObject2; +foo() ? exprString1 : exprBoolean1; // Union //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condNumber ? exprAny1 : exprAny2; @@ -44,19 +47,21 @@ var resultIsBoolean1 = condNumber ? exprBoolean1 : exprBoolean2; var resultIsNumber1 = condNumber ? exprNumber1 : exprNumber2; var resultIsString1 = condNumber ? exprString1 : exprString2; var resultIsObject1 = condNumber ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean1 = condNumber ? exprString1 : exprBoolean1; // Union var resultIsAny2 = 1 ? exprAny1 : exprAny2; var resultIsBoolean2 = 0 ? exprBoolean1 : exprBoolean2; var resultIsNumber2 = 0.123456789 ? exprNumber1 : exprNumber2; var resultIsString2 = - 10000000000000 ? exprString1 : exprString2; var resultIsObject2 = 1000000000000 ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean2 = 10000 ? exprString1 : exprBoolean1; // Union var resultIsAny3 = 1 * 0 ? exprAny1 : exprAny2; var resultIsBoolean3 = 1 + 1 ? exprBoolean1 : exprBoolean2; var resultIsNumber3 = "string".length ? exprNumber1 : exprNumber2; var resultIsString3 = foo() ? exprString1 : exprString2; var resultIsObject3 = foo() / array[1] ? exprIsObject1 : exprIsObject2; - +var resultIsStringOrBoolean3 = foo() / array[1] ? exprString1 : exprBoolean1; // Union //// [conditionalOperatorConditionIsNumberType.js] //Cond ? Expr1 : Expr2, Cond is of number type, Expr1 and Expr2 have the same type @@ -77,12 +82,14 @@ condNumber ? exprBoolean1 : exprBoolean2; condNumber ? exprNumber1 : exprNumber2; condNumber ? exprString1 : exprString2; condNumber ? exprIsObject1 : exprIsObject2; +condNumber ? exprString1 : exprBoolean1; // Union //Cond is a number type literal 1 ? exprAny1 : exprAny2; 0 ? exprBoolean1 : exprBoolean2; 0.123456789 ? exprNumber1 : exprNumber2; -10000000000000 ? exprString1 : exprString2; 1000000000000 ? exprIsObject1 : exprIsObject2; +10000 ? exprString1 : exprBoolean1; // Union //Cond is a number type expression function foo() { return 1; @@ -94,19 +101,23 @@ var array = [1, 2, 3]; "string".length ? exprNumber1 : exprNumber2; foo() ? exprString1 : exprString2; foo() / array[1] ? exprIsObject1 : exprIsObject2; +foo() ? exprString1 : exprBoolean1; // Union //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condNumber ? exprAny1 : exprAny2; var resultIsBoolean1 = condNumber ? exprBoolean1 : exprBoolean2; var resultIsNumber1 = condNumber ? exprNumber1 : exprNumber2; var resultIsString1 = condNumber ? exprString1 : exprString2; var resultIsObject1 = condNumber ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean1 = condNumber ? exprString1 : exprBoolean1; // Union var resultIsAny2 = 1 ? exprAny1 : exprAny2; var resultIsBoolean2 = 0 ? exprBoolean1 : exprBoolean2; var resultIsNumber2 = 0.123456789 ? exprNumber1 : exprNumber2; var resultIsString2 = -10000000000000 ? exprString1 : exprString2; var resultIsObject2 = 1000000000000 ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean2 = 10000 ? exprString1 : exprBoolean1; // Union var resultIsAny3 = 1 * 0 ? exprAny1 : exprAny2; var resultIsBoolean3 = 1 + 1 ? exprBoolean1 : exprBoolean2; var resultIsNumber3 = "string".length ? exprNumber1 : exprNumber2; var resultIsString3 = foo() ? exprString1 : exprString2; var resultIsObject3 = foo() / array[1] ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean3 = foo() / array[1] ? exprString1 : exprBoolean1; // Union diff --git a/tests/baselines/reference/conditionalOperatorConditionIsNumberType.types b/tests/baselines/reference/conditionalOperatorConditionIsNumberType.types index 3396885509a..99a81081d6b 100644 --- a/tests/baselines/reference/conditionalOperatorConditionIsNumberType.types +++ b/tests/baselines/reference/conditionalOperatorConditionIsNumberType.types @@ -66,6 +66,12 @@ condNumber ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +condNumber ? exprString1 : exprBoolean1; // Union +>condNumber ? exprString1 : exprBoolean1 : string | boolean +>condNumber : number +>exprString1 : string +>exprBoolean1 : boolean + //Cond is a number type literal 1 ? exprAny1 : exprAny2; >1 ? exprAny1 : exprAny2 : any @@ -93,6 +99,11 @@ condNumber ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +10000 ? exprString1 : exprBoolean1; // Union +>10000 ? exprString1 : exprBoolean1 : string | boolean +>exprString1 : string +>exprBoolean1 : boolean + //Cond is a number type expression function foo() { return 1 }; >foo : () => number @@ -137,6 +148,13 @@ foo() / array[1] ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +foo() ? exprString1 : exprBoolean1; // Union +>foo() ? exprString1 : exprBoolean1 : string | boolean +>foo() : number +>foo : () => number +>exprString1 : string +>exprBoolean1 : boolean + //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condNumber ? exprAny1 : exprAny2; >resultIsAny1 : any @@ -173,6 +191,13 @@ var resultIsObject1 = condNumber ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +var resultIsStringOrBoolean1 = condNumber ? exprString1 : exprBoolean1; // Union +>resultIsStringOrBoolean1 : string | boolean +>condNumber ? exprString1 : exprBoolean1 : string | boolean +>condNumber : number +>exprString1 : string +>exprBoolean1 : boolean + var resultIsAny2 = 1 ? exprAny1 : exprAny2; >resultIsAny2 : any >1 ? exprAny1 : exprAny2 : any @@ -204,6 +229,12 @@ var resultIsObject2 = 1000000000000 ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +var resultIsStringOrBoolean2 = 10000 ? exprString1 : exprBoolean1; // Union +>resultIsStringOrBoolean2 : string | boolean +>10000 ? exprString1 : exprBoolean1 : string | boolean +>exprString1 : string +>exprBoolean1 : boolean + var resultIsAny3 = 1 * 0 ? exprAny1 : exprAny2; >resultIsAny3 : any >1 * 0 ? exprAny1 : exprAny2 : any @@ -245,3 +276,14 @@ var resultIsObject3 = foo() / array[1] ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +var resultIsStringOrBoolean3 = foo() / array[1] ? exprString1 : exprBoolean1; // Union +>resultIsStringOrBoolean3 : string | boolean +>foo() / array[1] ? exprString1 : exprBoolean1 : string | boolean +>foo() / array[1] : number +>foo() : number +>foo : () => number +>array[1] : number +>array : number[] +>exprString1 : string +>exprBoolean1 : boolean + diff --git a/tests/baselines/reference/conditionalOperatorConditionIsObjectType.js b/tests/baselines/reference/conditionalOperatorConditionIsObjectType.js index 3f98398d94d..b628c21bd14 100644 --- a/tests/baselines/reference/conditionalOperatorConditionIsObjectType.js +++ b/tests/baselines/reference/conditionalOperatorConditionIsObjectType.js @@ -23,6 +23,7 @@ condObject ? exprBoolean1 : exprBoolean2; condObject ? exprNumber1 : exprNumber2; condObject ? exprString1 : exprString2; condObject ? exprIsObject1 : exprIsObject2; +condObject ? exprString1 : exprBoolean1; // union //Cond is an object type literal ((a: string) => a.length) ? exprAny1 : exprAny2; @@ -30,6 +31,7 @@ condObject ? exprIsObject1 : exprIsObject2; ({}) ? exprNumber1 : exprNumber2; ({ a: 1, b: "s" }) ? exprString1 : exprString2; ({ a: 1, b: "s" }) ? exprIsObject1 : exprIsObject2; +({ a: 1, b: "s" }) ? exprString1: exprBoolean1; // union //Cond is an object type expression foo() ? exprAny1 : exprAny2; @@ -37,6 +39,7 @@ new Date() ? exprBoolean1 : exprBoolean2; new C() ? exprNumber1 : exprNumber2; C.doIt() ? exprString1 : exprString2; condObject.valueOf() ? exprIsObject1 : exprIsObject2; +new Date() ? exprString1 : exprBoolean1; // union //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condObject ? exprAny1 : exprAny2; @@ -44,18 +47,21 @@ var resultIsBoolean1 = condObject ? exprBoolean1 : exprBoolean2; var resultIsNumber1 = condObject ? exprNumber1 : exprNumber2; var resultIsString1 = condObject ? exprString1 : exprString2; var resultIsObject1 = condObject ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean1 = condObject ? exprString1 : exprBoolean1; // union var resultIsAny2 = ((a: string) => a.length) ? exprAny1 : exprAny2; var resultIsBoolean2 = ((a: string) => a.length) ? exprBoolean1 : exprBoolean2; var resultIsNumber2 = ({}) ? exprNumber1 : exprNumber2; var resultIsString2 = ({ a: 1, b: "s" }) ? exprString1 : exprString2; var resultIsObject2 = ({ a: 1, b: "s" }) ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean2 = ({ a: 1, b: "s" }) ? exprString1 : exprBoolean1; // union var resultIsAny3 = foo() ? exprAny1 : exprAny2; var resultIsBoolean3 = new Date() ? exprBoolean1 : exprBoolean2; var resultIsNumber3 = new C() ? exprNumber1 : exprNumber2; var resultIsString3 = C.doIt() ? exprString1 : exprString2; var resultIsObject3 = condObject.valueOf() ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean3 = C.doIt() ? exprString1 : exprBoolean1; // union //// [conditionalOperatorConditionIsObjectType.js] @@ -86,31 +92,37 @@ condObject ? exprBoolean1 : exprBoolean2; condObject ? exprNumber1 : exprNumber2; condObject ? exprString1 : exprString2; condObject ? exprIsObject1 : exprIsObject2; +condObject ? exprString1 : exprBoolean1; // union //Cond is an object type literal (function (a) { return a.length; }) ? exprAny1 : exprAny2; (function (a) { return a.length; }) ? exprBoolean1 : exprBoolean2; ({}) ? exprNumber1 : exprNumber2; ({ a: 1, b: "s" }) ? exprString1 : exprString2; ({ a: 1, b: "s" }) ? exprIsObject1 : exprIsObject2; +({ a: 1, b: "s" }) ? exprString1 : exprBoolean1; // union //Cond is an object type expression foo() ? exprAny1 : exprAny2; new Date() ? exprBoolean1 : exprBoolean2; new C() ? exprNumber1 : exprNumber2; C.doIt() ? exprString1 : exprString2; condObject.valueOf() ? exprIsObject1 : exprIsObject2; +new Date() ? exprString1 : exprBoolean1; // union //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condObject ? exprAny1 : exprAny2; var resultIsBoolean1 = condObject ? exprBoolean1 : exprBoolean2; var resultIsNumber1 = condObject ? exprNumber1 : exprNumber2; var resultIsString1 = condObject ? exprString1 : exprString2; var resultIsObject1 = condObject ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean1 = condObject ? exprString1 : exprBoolean1; // union var resultIsAny2 = (function (a) { return a.length; }) ? exprAny1 : exprAny2; var resultIsBoolean2 = (function (a) { return a.length; }) ? exprBoolean1 : exprBoolean2; var resultIsNumber2 = ({}) ? exprNumber1 : exprNumber2; var resultIsString2 = ({ a: 1, b: "s" }) ? exprString1 : exprString2; var resultIsObject2 = ({ a: 1, b: "s" }) ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean2 = ({ a: 1, b: "s" }) ? exprString1 : exprBoolean1; // union var resultIsAny3 = foo() ? exprAny1 : exprAny2; var resultIsBoolean3 = new Date() ? exprBoolean1 : exprBoolean2; var resultIsNumber3 = new C() ? exprNumber1 : exprNumber2; var resultIsString3 = C.doIt() ? exprString1 : exprString2; var resultIsObject3 = condObject.valueOf() ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean3 = C.doIt() ? exprString1 : exprBoolean1; // union diff --git a/tests/baselines/reference/conditionalOperatorConditionIsObjectType.types b/tests/baselines/reference/conditionalOperatorConditionIsObjectType.types index 36c15d64c54..171871c5dcf 100644 --- a/tests/baselines/reference/conditionalOperatorConditionIsObjectType.types +++ b/tests/baselines/reference/conditionalOperatorConditionIsObjectType.types @@ -74,6 +74,12 @@ condObject ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +condObject ? exprString1 : exprBoolean1; // union +>condObject ? exprString1 : exprBoolean1 : string | boolean +>condObject : Object +>exprString1 : string +>exprBoolean1 : boolean + //Cond is an object type literal ((a: string) => a.length) ? exprAny1 : exprAny2; >((a: string) => a.length) ? exprAny1 : exprAny2 : any @@ -122,6 +128,15 @@ condObject ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +({ a: 1, b: "s" }) ? exprString1: exprBoolean1; // union +>({ a: 1, b: "s" }) ? exprString1: exprBoolean1 : string | boolean +>({ a: 1, b: "s" }) : { a: number; b: string; } +>{ a: 1, b: "s" } : { a: number; b: string; } +>a : number +>b : string +>exprString1 : string +>exprBoolean1 : boolean + //Cond is an object type expression foo() ? exprAny1 : exprAny2; >foo() ? exprAny1 : exprAny2 : any @@ -162,6 +177,13 @@ condObject.valueOf() ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +new Date() ? exprString1 : exprBoolean1; // union +>new Date() ? exprString1 : exprBoolean1 : string | boolean +>new Date() : Date +>Date : { (): string; new (): Date; new (value: number): Date; new (value: string): Date; new (year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): Date; prototype: Date; parse(s: string): number; UTC(year: number, month: number, date?: number, hours?: number, minutes?: number, seconds?: number, ms?: number): number; now(): number; } +>exprString1 : string +>exprBoolean1 : boolean + //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condObject ? exprAny1 : exprAny2; >resultIsAny1 : any @@ -198,6 +220,13 @@ var resultIsObject1 = condObject ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +var resultIsStringOrBoolean1 = condObject ? exprString1 : exprBoolean1; // union +>resultIsStringOrBoolean1 : string | boolean +>condObject ? exprString1 : exprBoolean1 : string | boolean +>condObject : Object +>exprString1 : string +>exprBoolean1 : boolean + var resultIsAny2 = ((a: string) => a.length) ? exprAny1 : exprAny2; >resultIsAny2 : any >((a: string) => a.length) ? exprAny1 : exprAny2 : any @@ -250,6 +279,16 @@ var resultIsObject2 = ({ a: 1, b: "s" }) ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +var resultIsStringOrBoolean2 = ({ a: 1, b: "s" }) ? exprString1 : exprBoolean1; // union +>resultIsStringOrBoolean2 : string | boolean +>({ a: 1, b: "s" }) ? exprString1 : exprBoolean1 : string | boolean +>({ a: 1, b: "s" }) : { a: number; b: string; } +>{ a: 1, b: "s" } : { a: number; b: string; } +>a : number +>b : string +>exprString1 : string +>exprBoolean1 : boolean + var resultIsAny3 = foo() ? exprAny1 : exprAny2; >resultIsAny3 : any >foo() ? exprAny1 : exprAny2 : any @@ -294,3 +333,13 @@ var resultIsObject3 = condObject.valueOf() ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +var resultIsStringOrBoolean3 = C.doIt() ? exprString1 : exprBoolean1; // union +>resultIsStringOrBoolean3 : string | boolean +>C.doIt() ? exprString1 : exprBoolean1 : string | boolean +>C.doIt() : void +>C.doIt : () => void +>C : typeof C +>doIt : () => void +>exprString1 : string +>exprBoolean1 : boolean + diff --git a/tests/baselines/reference/conditionalOperatorConditoinIsAnyType.js b/tests/baselines/reference/conditionalOperatorConditoinIsAnyType.js index 5869023d17d..80cfaf97f26 100644 --- a/tests/baselines/reference/conditionalOperatorConditoinIsAnyType.js +++ b/tests/baselines/reference/conditionalOperatorConditoinIsAnyType.js @@ -21,6 +21,7 @@ condAny ? exprBoolean1 : exprBoolean2; condAny ? exprNumber1 : exprNumber2; condAny ? exprString1 : exprString2; condAny ? exprIsObject1 : exprIsObject2; +condAny ? exprString1 : exprBoolean1; // union //Cond is an any type literal null ? exprAny1 : exprAny2; @@ -28,6 +29,7 @@ null ? exprBoolean1 : exprBoolean2; undefined ? exprNumber1 : exprNumber2; [null, undefined] ? exprString1 : exprString2; [null, undefined] ? exprIsObject1 : exprIsObject2; +undefined ? exprString1 : exprBoolean1; // union //Cond is an any type expression x.doSomeThing() ? exprAny1 : exprAny2; @@ -35,6 +37,7 @@ x("x") ? exprBoolean1 : exprBoolean2; x(x) ? exprNumber1 : exprNumber2; x("x") ? exprString1 : exprString2; x.doSomeThing() ? exprIsObject1 : exprIsObject2; +x.doSomeThing() ? exprString1 : exprBoolean1; // union //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condAny ? exprAny1 : exprAny2; @@ -42,19 +45,23 @@ var resultIsBoolean1 = condAny ? exprBoolean1 : exprBoolean2; var resultIsNumber1 = condAny ? exprNumber1 : exprNumber2; var resultIsString1 = condAny ? exprString1 : exprString2; var resultIsObject1 = condAny ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean1 = condAny ? exprString1 : exprBoolean1; // union var resultIsAny2 = null ? exprAny1 : exprAny2; var resultIsBoolean2 = null ? exprBoolean1 : exprBoolean2; var resultIsNumber2 = undefined ? exprNumber1 : exprNumber2; var resultIsString2 = [null, undefined] ? exprString1 : exprString2; var resultIsObject2 = [null, undefined] ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean2 = null ? exprString1 : exprBoolean1; // union +var resultIsStringOrBoolean3 = undefined ? exprString1 : exprBoolean1; // union +var resultIsStringOrBoolean4 = [null, undefined] ? exprString1 : exprBoolean1; // union var resultIsAny3 = x.doSomeThing() ? exprAny1 : exprAny2; var resultIsBoolean3 = x("x") ? exprBoolean1 : exprBoolean2; var resultIsNumber3 = x(x) ? exprNumber1 : exprNumber2; var resultIsString3 = x("x") ? exprString1 : exprString2; var resultIsObject3 = x.doSomeThing() ? exprIsObject1 : exprIsObject2; - +var resultIsStringOrBoolean5 = x.doSomeThing() ? exprString1 : exprBoolean1; // union //// [conditionalOperatorConditoinIsAnyType.js] //Cond ? Expr1 : Expr2, Cond is of any type, Expr1 and Expr2 have the same type @@ -76,31 +83,39 @@ condAny ? exprBoolean1 : exprBoolean2; condAny ? exprNumber1 : exprNumber2; condAny ? exprString1 : exprString2; condAny ? exprIsObject1 : exprIsObject2; +condAny ? exprString1 : exprBoolean1; // union //Cond is an any type literal null ? exprAny1 : exprAny2; null ? exprBoolean1 : exprBoolean2; undefined ? exprNumber1 : exprNumber2; [null, undefined] ? exprString1 : exprString2; [null, undefined] ? exprIsObject1 : exprIsObject2; +undefined ? exprString1 : exprBoolean1; // union //Cond is an any type expression x.doSomeThing() ? exprAny1 : exprAny2; x("x") ? exprBoolean1 : exprBoolean2; x(x) ? exprNumber1 : exprNumber2; x("x") ? exprString1 : exprString2; x.doSomeThing() ? exprIsObject1 : exprIsObject2; +x.doSomeThing() ? exprString1 : exprBoolean1; // union //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condAny ? exprAny1 : exprAny2; var resultIsBoolean1 = condAny ? exprBoolean1 : exprBoolean2; var resultIsNumber1 = condAny ? exprNumber1 : exprNumber2; var resultIsString1 = condAny ? exprString1 : exprString2; var resultIsObject1 = condAny ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean1 = condAny ? exprString1 : exprBoolean1; // union var resultIsAny2 = null ? exprAny1 : exprAny2; var resultIsBoolean2 = null ? exprBoolean1 : exprBoolean2; var resultIsNumber2 = undefined ? exprNumber1 : exprNumber2; var resultIsString2 = [null, undefined] ? exprString1 : exprString2; var resultIsObject2 = [null, undefined] ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean2 = null ? exprString1 : exprBoolean1; // union +var resultIsStringOrBoolean3 = undefined ? exprString1 : exprBoolean1; // union +var resultIsStringOrBoolean4 = [null, undefined] ? exprString1 : exprBoolean1; // union var resultIsAny3 = x.doSomeThing() ? exprAny1 : exprAny2; var resultIsBoolean3 = x("x") ? exprBoolean1 : exprBoolean2; var resultIsNumber3 = x(x) ? exprNumber1 : exprNumber2; var resultIsString3 = x("x") ? exprString1 : exprString2; var resultIsObject3 = x.doSomeThing() ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean5 = x.doSomeThing() ? exprString1 : exprBoolean1; // union diff --git a/tests/baselines/reference/conditionalOperatorConditoinIsAnyType.types b/tests/baselines/reference/conditionalOperatorConditoinIsAnyType.types index 9f5fc9326bb..6542377795f 100644 --- a/tests/baselines/reference/conditionalOperatorConditoinIsAnyType.types +++ b/tests/baselines/reference/conditionalOperatorConditoinIsAnyType.types @@ -69,6 +69,12 @@ condAny ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +condAny ? exprString1 : exprBoolean1; // union +>condAny ? exprString1 : exprBoolean1 : string | boolean +>condAny : any +>exprString1 : string +>exprBoolean1 : boolean + //Cond is an any type literal null ? exprAny1 : exprAny2; >null ? exprAny1 : exprAny2 : any @@ -100,6 +106,12 @@ undefined ? exprNumber1 : exprNumber2; >exprIsObject1 : Object >exprIsObject2 : Object +undefined ? exprString1 : exprBoolean1; // union +>undefined ? exprString1 : exprBoolean1 : string | boolean +>undefined : undefined +>exprString1 : string +>exprBoolean1 : boolean + //Cond is an any type expression x.doSomeThing() ? exprAny1 : exprAny2; >x.doSomeThing() ? exprAny1 : exprAny2 : any @@ -141,6 +153,15 @@ x.doSomeThing() ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +x.doSomeThing() ? exprString1 : exprBoolean1; // union +>x.doSomeThing() ? exprString1 : exprBoolean1 : string | boolean +>x.doSomeThing() : any +>x.doSomeThing : any +>x : any +>doSomeThing : any +>exprString1 : string +>exprBoolean1 : boolean + //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condAny ? exprAny1 : exprAny2; >resultIsAny1 : any @@ -177,6 +198,13 @@ var resultIsObject1 = condAny ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +var resultIsStringOrBoolean1 = condAny ? exprString1 : exprBoolean1; // union +>resultIsStringOrBoolean1 : string | boolean +>condAny ? exprString1 : exprBoolean1 : string | boolean +>condAny : any +>exprString1 : string +>exprBoolean1 : boolean + var resultIsAny2 = null ? exprAny1 : exprAny2; >resultIsAny2 : any >null ? exprAny1 : exprAny2 : any @@ -212,6 +240,27 @@ var resultIsObject2 = [null, undefined] ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +var resultIsStringOrBoolean2 = null ? exprString1 : exprBoolean1; // union +>resultIsStringOrBoolean2 : string | boolean +>null ? exprString1 : exprBoolean1 : string | boolean +>exprString1 : string +>exprBoolean1 : boolean + +var resultIsStringOrBoolean3 = undefined ? exprString1 : exprBoolean1; // union +>resultIsStringOrBoolean3 : string | boolean +>undefined ? exprString1 : exprBoolean1 : string | boolean +>undefined : undefined +>exprString1 : string +>exprBoolean1 : boolean + +var resultIsStringOrBoolean4 = [null, undefined] ? exprString1 : exprBoolean1; // union +>resultIsStringOrBoolean4 : string | boolean +>[null, undefined] ? exprString1 : exprBoolean1 : string | boolean +>[null, undefined] : null[] +>undefined : undefined +>exprString1 : string +>exprBoolean1 : boolean + var resultIsAny3 = x.doSomeThing() ? exprAny1 : exprAny2; >resultIsAny3 : any >x.doSomeThing() ? exprAny1 : exprAny2 : any @@ -257,3 +306,13 @@ var resultIsObject3 = x.doSomeThing() ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +var resultIsStringOrBoolean5 = x.doSomeThing() ? exprString1 : exprBoolean1; // union +>resultIsStringOrBoolean5 : string | boolean +>x.doSomeThing() ? exprString1 : exprBoolean1 : string | boolean +>x.doSomeThing() : any +>x.doSomeThing : any +>x : any +>doSomeThing : any +>exprString1 : string +>exprBoolean1 : boolean + diff --git a/tests/baselines/reference/conditionalOperatorConditoinIsStringType.js b/tests/baselines/reference/conditionalOperatorConditoinIsStringType.js index 4bd67a40640..02c398e89e1 100644 --- a/tests/baselines/reference/conditionalOperatorConditoinIsStringType.js +++ b/tests/baselines/reference/conditionalOperatorConditoinIsStringType.js @@ -20,6 +20,7 @@ condString ? exprBoolean1 : exprBoolean2; condString ? exprNumber1 : exprNumber2; condString ? exprString1 : exprString2; condString ? exprIsObject1 : exprIsObject2; +condString ? exprString1 : exprBoolean1; // union //Cond is a string type literal "" ? exprAny1 : exprAny2; @@ -27,6 +28,7 @@ condString ? exprIsObject1 : exprIsObject2; 'c' ? exprNumber1 : exprNumber2; 'string' ? exprString1 : exprString2; " " ? exprIsObject1 : exprIsObject2; +"hello " ? exprString1 : exprBoolean1; // union //Cond is a string type expression function foo() { return "string" }; @@ -37,6 +39,7 @@ condString.toUpperCase ? exprBoolean1 : exprBoolean2; condString + "string" ? exprNumber1 : exprNumber2; foo() ? exprString1 : exprString2; array[1] ? exprIsObject1 : exprIsObject2; +foo() ? exprString1 : exprBoolean1; // union //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condString ? exprAny1 : exprAny2; @@ -44,19 +47,22 @@ var resultIsBoolean1 = condString ? exprBoolean1 : exprBoolean2; var resultIsNumber1 = condString ? exprNumber1 : exprNumber2; var resultIsString1 = condString ? exprString1 : exprString2; var resultIsObject1 = condString ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean1 = condString ? exprString1 : exprBoolean1; // union var resultIsAny2 = "" ? exprAny1 : exprAny2; var resultIsBoolean2 = "string" ? exprBoolean1 : exprBoolean2; var resultIsNumber2 = 'c' ? exprNumber1 : exprNumber2; var resultIsString2 = 'string' ? exprString1 : exprString2; var resultIsObject2 = " " ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean2 = "hello" ? exprString1 : exprBoolean1; // union var resultIsAny3 = typeof condString ? exprAny1 : exprAny2; var resultIsBoolean3 = condString.toUpperCase ? exprBoolean1 : exprBoolean2; var resultIsNumber3 = condString + "string" ? exprNumber1 : exprNumber2; var resultIsString3 = foo() ? exprString1 : exprString2; var resultIsObject3 = array[1] ? exprIsObject1 : exprIsObject2; - +var resultIsStringOrBoolean3 = typeof condString ? exprString1 : exprBoolean1; // union +var resultIsStringOrBoolean4 = condString.toUpperCase ? exprString1 : exprBoolean1; // union //// [conditionalOperatorConditoinIsStringType.js] //Cond ? Expr1 : Expr2, Cond is of string type, Expr1 and Expr2 have the same type @@ -77,12 +83,14 @@ condString ? exprBoolean1 : exprBoolean2; condString ? exprNumber1 : exprNumber2; condString ? exprString1 : exprString2; condString ? exprIsObject1 : exprIsObject2; +condString ? exprString1 : exprBoolean1; // union //Cond is a string type literal "" ? exprAny1 : exprAny2; "string" ? exprBoolean1 : exprBoolean2; 'c' ? exprNumber1 : exprNumber2; 'string' ? exprString1 : exprString2; " " ? exprIsObject1 : exprIsObject2; +"hello " ? exprString1 : exprBoolean1; // union //Cond is a string type expression function foo() { return "string"; @@ -94,19 +102,24 @@ condString.toUpperCase ? exprBoolean1 : exprBoolean2; condString + "string" ? exprNumber1 : exprNumber2; foo() ? exprString1 : exprString2; array[1] ? exprIsObject1 : exprIsObject2; +foo() ? exprString1 : exprBoolean1; // union //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condString ? exprAny1 : exprAny2; var resultIsBoolean1 = condString ? exprBoolean1 : exprBoolean2; var resultIsNumber1 = condString ? exprNumber1 : exprNumber2; var resultIsString1 = condString ? exprString1 : exprString2; var resultIsObject1 = condString ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean1 = condString ? exprString1 : exprBoolean1; // union var resultIsAny2 = "" ? exprAny1 : exprAny2; var resultIsBoolean2 = "string" ? exprBoolean1 : exprBoolean2; var resultIsNumber2 = 'c' ? exprNumber1 : exprNumber2; var resultIsString2 = 'string' ? exprString1 : exprString2; var resultIsObject2 = " " ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean2 = "hello" ? exprString1 : exprBoolean1; // union var resultIsAny3 = typeof condString ? exprAny1 : exprAny2; var resultIsBoolean3 = condString.toUpperCase ? exprBoolean1 : exprBoolean2; var resultIsNumber3 = condString + "string" ? exprNumber1 : exprNumber2; var resultIsString3 = foo() ? exprString1 : exprString2; var resultIsObject3 = array[1] ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean3 = typeof condString ? exprString1 : exprBoolean1; // union +var resultIsStringOrBoolean4 = condString.toUpperCase ? exprString1 : exprBoolean1; // union diff --git a/tests/baselines/reference/conditionalOperatorConditoinIsStringType.types b/tests/baselines/reference/conditionalOperatorConditoinIsStringType.types index 668e0fc437c..45a4db8d295 100644 --- a/tests/baselines/reference/conditionalOperatorConditoinIsStringType.types +++ b/tests/baselines/reference/conditionalOperatorConditoinIsStringType.types @@ -66,6 +66,12 @@ condString ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +condString ? exprString1 : exprBoolean1; // union +>condString ? exprString1 : exprBoolean1 : string | boolean +>condString : string +>exprString1 : string +>exprBoolean1 : boolean + //Cond is a string type literal "" ? exprAny1 : exprAny2; >"" ? exprAny1 : exprAny2 : any @@ -92,6 +98,11 @@ condString ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +"hello " ? exprString1 : exprBoolean1; // union +>"hello " ? exprString1 : exprBoolean1 : string | boolean +>exprString1 : string +>exprBoolean1 : boolean + //Cond is a string type expression function foo() { return "string" }; >foo : () => string @@ -136,6 +147,13 @@ array[1] ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +foo() ? exprString1 : exprBoolean1; // union +>foo() ? exprString1 : exprBoolean1 : string | boolean +>foo() : string +>foo : () => string +>exprString1 : string +>exprBoolean1 : boolean + //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condString ? exprAny1 : exprAny2; >resultIsAny1 : any @@ -172,6 +190,13 @@ var resultIsObject1 = condString ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +var resultIsStringOrBoolean1 = condString ? exprString1 : exprBoolean1; // union +>resultIsStringOrBoolean1 : string | boolean +>condString ? exprString1 : exprBoolean1 : string | boolean +>condString : string +>exprString1 : string +>exprBoolean1 : boolean + var resultIsAny2 = "" ? exprAny1 : exprAny2; >resultIsAny2 : any >"" ? exprAny1 : exprAny2 : any @@ -202,6 +227,12 @@ var resultIsObject2 = " " ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +var resultIsStringOrBoolean2 = "hello" ? exprString1 : exprBoolean1; // union +>resultIsStringOrBoolean2 : string | boolean +>"hello" ? exprString1 : exprBoolean1 : string | boolean +>exprString1 : string +>exprBoolean1 : boolean + var resultIsAny3 = typeof condString ? exprAny1 : exprAny2; >resultIsAny3 : any >typeof condString ? exprAny1 : exprAny2 : any @@ -243,3 +274,20 @@ var resultIsObject3 = array[1] ? exprIsObject1 : exprIsObject2; >exprIsObject1 : Object >exprIsObject2 : Object +var resultIsStringOrBoolean3 = typeof condString ? exprString1 : exprBoolean1; // union +>resultIsStringOrBoolean3 : string | boolean +>typeof condString ? exprString1 : exprBoolean1 : string | boolean +>typeof condString : string +>condString : string +>exprString1 : string +>exprBoolean1 : boolean + +var resultIsStringOrBoolean4 = condString.toUpperCase ? exprString1 : exprBoolean1; // union +>resultIsStringOrBoolean4 : string | boolean +>condString.toUpperCase ? exprString1 : exprBoolean1 : string | boolean +>condString.toUpperCase : () => string +>condString : string +>toUpperCase : () => string +>exprString1 : string +>exprBoolean1 : boolean + diff --git a/tests/baselines/reference/conditionalOperatorWithoutIdenticalBCT.errors.txt b/tests/baselines/reference/conditionalOperatorWithoutIdenticalBCT.errors.txt index 27c08308c33..e04411e8f69 100644 --- a/tests/baselines/reference/conditionalOperatorWithoutIdenticalBCT.errors.txt +++ b/tests/baselines/reference/conditionalOperatorWithoutIdenticalBCT.errors.txt @@ -4,13 +4,13 @@ tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorWithou tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorWithoutIdenticalBCT.ts(16,5): error TS2323: Type 'A | B' is not assignable to type 'B'. Type 'A' is not assignable to type 'B'. Property 'propertyB' is missing in type 'A'. -tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorWithoutIdenticalBCT.ts(18,5): error TS2323: Type '((m: X) => number) | ((n: X) => string)' is not assignable to type '(t: X) => number'. +tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorWithoutIdenticalBCT.ts(19,5): error TS2323: Type '((m: X) => number) | ((n: X) => string)' is not assignable to type '(t: X) => number'. Type '(n: X) => string' is not assignable to type '(t: X) => number'. Type 'string' is not assignable to type 'number'. -tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorWithoutIdenticalBCT.ts(19,5): error TS2323: Type '((m: X) => number) | ((n: X) => string)' is not assignable to type '(t: X) => string'. +tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorWithoutIdenticalBCT.ts(20,5): error TS2323: Type '((m: X) => number) | ((n: X) => string)' is not assignable to type '(t: X) => string'. Type '(m: X) => number' is not assignable to type '(t: X) => string'. Type 'number' is not assignable to type 'string'. -tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorWithoutIdenticalBCT.ts(20,5): error TS2323: Type '((m: X) => number) | ((n: X) => string)' is not assignable to type '(t: X) => boolean'. +tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorWithoutIdenticalBCT.ts(21,5): error TS2323: Type '((m: X) => number) | ((n: X) => string)' is not assignable to type '(t: X) => boolean'. Type '(m: X) => number' is not assignable to type '(t: X) => boolean'. Type 'number' is not assignable to type 'boolean'. @@ -40,6 +40,7 @@ tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorWithou !!! error TS2323: Type 'A | B' is not assignable to type 'B'. !!! error TS2323: Type 'A' is not assignable to type 'B'. !!! error TS2323: Property 'propertyB' is missing in type 'A'. + var result31: A | B = true ? a : b; var result4: (t: X) => number = true ? (m) => m.propertyX1 : (n) => n.propertyX2; ~~~~~~~ @@ -55,4 +56,6 @@ tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorWithou ~~~~~~~ !!! error TS2323: Type '((m: X) => number) | ((n: X) => string)' is not assignable to type '(t: X) => boolean'. !!! error TS2323: Type '(m: X) => number' is not assignable to type '(t: X) => boolean'. -!!! error TS2323: Type 'number' is not assignable to type 'boolean'. \ No newline at end of file +!!! error TS2323: Type 'number' is not assignable to type 'boolean'. + var result61: (t: X) => number| string = true ? (m) => m.propertyX1 : (n) => n.propertyX2; + \ No newline at end of file diff --git a/tests/baselines/reference/conditionalOperatorWithoutIdenticalBCT.js b/tests/baselines/reference/conditionalOperatorWithoutIdenticalBCT.js index b6376dd781f..83262ed1301 100644 --- a/tests/baselines/reference/conditionalOperatorWithoutIdenticalBCT.js +++ b/tests/baselines/reference/conditionalOperatorWithoutIdenticalBCT.js @@ -15,10 +15,13 @@ var result1 = true ? a : b; //Be contextually typed and and bct is not identical, results in errors that union type is not assignable to target var result2: A = true ? a : b; var result3: B = true ? a : b; +var result31: A | B = true ? a : b; var result4: (t: X) => number = true ? (m) => m.propertyX1 : (n) => n.propertyX2; var result5: (t: X) => string = true ? (m) => m.propertyX1 : (n) => n.propertyX2; -var result6: (t: X) => boolean = true ? (m) => m.propertyX1 : (n) => n.propertyX2; +var result6: (t: X) => boolean = true ? (m) => m.propertyX1 : (n) => n.propertyX2; +var result61: (t: X) => number| string = true ? (m) => m.propertyX1 : (n) => n.propertyX2; + //// [conditionalOperatorWithoutIdenticalBCT.js] var __extends = this.__extends || function (d, b) { @@ -59,6 +62,8 @@ var result1 = true ? a : b; //Be contextually typed and and bct is not identical, results in errors that union type is not assignable to target var result2 = true ? a : b; var result3 = true ? a : b; +var result31 = true ? a : b; var result4 = true ? function (m) { return m.propertyX1; } : function (n) { return n.propertyX2; }; var result5 = true ? function (m) { return m.propertyX1; } : function (n) { return n.propertyX2; }; var result6 = true ? function (m) { return m.propertyX1; } : function (n) { return n.propertyX2; }; +var result61 = true ? function (m) { return m.propertyX1; } : function (n) { return n.propertyX2; }; diff --git a/tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorConditionIsBooleanType.ts b/tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorConditionIsBooleanType.ts index 80c2a8e8ec8..67b609e03e9 100644 --- a/tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorConditionIsBooleanType.ts +++ b/tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorConditionIsBooleanType.ts @@ -19,6 +19,7 @@ condBoolean ? exprBoolean1 : exprBoolean2; condBoolean ? exprNumber1 : exprNumber2; condBoolean ? exprString1 : exprString2; condBoolean ? exprIsObject1 : exprIsObject2; +condBoolean ? exprString1 : exprBoolean1; // union //Cond is a boolean type literal true ? exprAny1 : exprAny2; @@ -26,6 +27,7 @@ false ? exprBoolean1 : exprBoolean2; true ? exprNumber1 : exprNumber2; false ? exprString1 : exprString2; true ? exprIsObject1 : exprIsObject2; +true ? exprString1 : exprBoolean1; // union //Cond is a boolean type expression !true ? exprAny1 : exprAny2; @@ -33,6 +35,7 @@ typeof "123" == "string" ? exprBoolean1 : exprBoolean2; 2 > 1 ? exprNumber1 : exprNumber2; null === undefined ? exprString1 : exprString2; true || false ? exprIsObject1 : exprIsObject2; +null === undefined ? exprString1 : exprBoolean1; // union //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condBoolean ? exprAny1 : exprAny2; @@ -40,15 +43,19 @@ var resultIsBoolean1 = condBoolean ? exprBoolean1 : exprBoolean2; var resultIsNumber1 = condBoolean ? exprNumber1 : exprNumber2; var resultIsString1 = condBoolean ? exprString1 : exprString2; var resultIsObject1 = condBoolean ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean1 = condBoolean ? exprString1 : exprBoolean1; // union var resultIsAny2 = true ? exprAny1 : exprAny2; var resultIsBoolean2 = false ? exprBoolean1 : exprBoolean2; var resultIsNumber2 = true ? exprNumber1 : exprNumber2; var resultIsString2 = false ? exprString1 : exprString2; var resultIsObject2 = true ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean2 = true ? exprString1 : exprBoolean1; // union +var resultIsStringOrBoolean3 = false ? exprString1 : exprBoolean1; // union var resultIsAny3 = !true ? exprAny1 : exprAny2; var resultIsBoolean3 = typeof "123" == "string" ? exprBoolean1 : exprBoolean2; var resultIsNumber3 = 2 > 1 ? exprNumber1 : exprNumber2; var resultIsString3 = null === undefined ? exprString1 : exprString2; var resultIsObject3 = true || false ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean4 = typeof "123" === "string" ? exprString1 : exprBoolean1; // union diff --git a/tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorConditionIsNumberType.ts b/tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorConditionIsNumberType.ts index 5ec1beb9342..2e2c39ef316 100644 --- a/tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorConditionIsNumberType.ts +++ b/tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorConditionIsNumberType.ts @@ -19,6 +19,7 @@ condNumber ? exprBoolean1 : exprBoolean2; condNumber ? exprNumber1 : exprNumber2; condNumber ? exprString1 : exprString2; condNumber ? exprIsObject1 : exprIsObject2; +condNumber ? exprString1 : exprBoolean1; // Union //Cond is a number type literal 1 ? exprAny1 : exprAny2; @@ -26,6 +27,7 @@ condNumber ? exprIsObject1 : exprIsObject2; 0.123456789 ? exprNumber1 : exprNumber2; - 10000000000000 ? exprString1 : exprString2; 1000000000000 ? exprIsObject1 : exprIsObject2; +10000 ? exprString1 : exprBoolean1; // Union //Cond is a number type expression function foo() { return 1 }; @@ -36,6 +38,7 @@ var array = [1, 2, 3]; "string".length ? exprNumber1 : exprNumber2; foo() ? exprString1 : exprString2; foo() / array[1] ? exprIsObject1 : exprIsObject2; +foo() ? exprString1 : exprBoolean1; // Union //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condNumber ? exprAny1 : exprAny2; @@ -43,15 +46,18 @@ var resultIsBoolean1 = condNumber ? exprBoolean1 : exprBoolean2; var resultIsNumber1 = condNumber ? exprNumber1 : exprNumber2; var resultIsString1 = condNumber ? exprString1 : exprString2; var resultIsObject1 = condNumber ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean1 = condNumber ? exprString1 : exprBoolean1; // Union var resultIsAny2 = 1 ? exprAny1 : exprAny2; var resultIsBoolean2 = 0 ? exprBoolean1 : exprBoolean2; var resultIsNumber2 = 0.123456789 ? exprNumber1 : exprNumber2; var resultIsString2 = - 10000000000000 ? exprString1 : exprString2; var resultIsObject2 = 1000000000000 ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean2 = 10000 ? exprString1 : exprBoolean1; // Union var resultIsAny3 = 1 * 0 ? exprAny1 : exprAny2; var resultIsBoolean3 = 1 + 1 ? exprBoolean1 : exprBoolean2; var resultIsNumber3 = "string".length ? exprNumber1 : exprNumber2; var resultIsString3 = foo() ? exprString1 : exprString2; var resultIsObject3 = foo() / array[1] ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean3 = foo() / array[1] ? exprString1 : exprBoolean1; // Union \ No newline at end of file diff --git a/tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorConditionIsObjectType.ts b/tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorConditionIsObjectType.ts index 5c8dcf0a13e..24b6970e12b 100644 --- a/tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorConditionIsObjectType.ts +++ b/tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorConditionIsObjectType.ts @@ -22,6 +22,7 @@ condObject ? exprBoolean1 : exprBoolean2; condObject ? exprNumber1 : exprNumber2; condObject ? exprString1 : exprString2; condObject ? exprIsObject1 : exprIsObject2; +condObject ? exprString1 : exprBoolean1; // union //Cond is an object type literal ((a: string) => a.length) ? exprAny1 : exprAny2; @@ -29,6 +30,7 @@ condObject ? exprIsObject1 : exprIsObject2; ({}) ? exprNumber1 : exprNumber2; ({ a: 1, b: "s" }) ? exprString1 : exprString2; ({ a: 1, b: "s" }) ? exprIsObject1 : exprIsObject2; +({ a: 1, b: "s" }) ? exprString1: exprBoolean1; // union //Cond is an object type expression foo() ? exprAny1 : exprAny2; @@ -36,6 +38,7 @@ new Date() ? exprBoolean1 : exprBoolean2; new C() ? exprNumber1 : exprNumber2; C.doIt() ? exprString1 : exprString2; condObject.valueOf() ? exprIsObject1 : exprIsObject2; +new Date() ? exprString1 : exprBoolean1; // union //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condObject ? exprAny1 : exprAny2; @@ -43,15 +46,18 @@ var resultIsBoolean1 = condObject ? exprBoolean1 : exprBoolean2; var resultIsNumber1 = condObject ? exprNumber1 : exprNumber2; var resultIsString1 = condObject ? exprString1 : exprString2; var resultIsObject1 = condObject ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean1 = condObject ? exprString1 : exprBoolean1; // union var resultIsAny2 = ((a: string) => a.length) ? exprAny1 : exprAny2; var resultIsBoolean2 = ((a: string) => a.length) ? exprBoolean1 : exprBoolean2; var resultIsNumber2 = ({}) ? exprNumber1 : exprNumber2; var resultIsString2 = ({ a: 1, b: "s" }) ? exprString1 : exprString2; var resultIsObject2 = ({ a: 1, b: "s" }) ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean2 = ({ a: 1, b: "s" }) ? exprString1 : exprBoolean1; // union var resultIsAny3 = foo() ? exprAny1 : exprAny2; var resultIsBoolean3 = new Date() ? exprBoolean1 : exprBoolean2; var resultIsNumber3 = new C() ? exprNumber1 : exprNumber2; var resultIsString3 = C.doIt() ? exprString1 : exprString2; var resultIsObject3 = condObject.valueOf() ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean3 = C.doIt() ? exprString1 : exprBoolean1; // union diff --git a/tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorConditoinIsAnyType.ts b/tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorConditoinIsAnyType.ts index 67ef99da141..3a03dfdacaa 100644 --- a/tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorConditoinIsAnyType.ts +++ b/tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorConditoinIsAnyType.ts @@ -20,6 +20,7 @@ condAny ? exprBoolean1 : exprBoolean2; condAny ? exprNumber1 : exprNumber2; condAny ? exprString1 : exprString2; condAny ? exprIsObject1 : exprIsObject2; +condAny ? exprString1 : exprBoolean1; // union //Cond is an any type literal null ? exprAny1 : exprAny2; @@ -27,6 +28,7 @@ null ? exprBoolean1 : exprBoolean2; undefined ? exprNumber1 : exprNumber2; [null, undefined] ? exprString1 : exprString2; [null, undefined] ? exprIsObject1 : exprIsObject2; +undefined ? exprString1 : exprBoolean1; // union //Cond is an any type expression x.doSomeThing() ? exprAny1 : exprAny2; @@ -34,6 +36,7 @@ x("x") ? exprBoolean1 : exprBoolean2; x(x) ? exprNumber1 : exprNumber2; x("x") ? exprString1 : exprString2; x.doSomeThing() ? exprIsObject1 : exprIsObject2; +x.doSomeThing() ? exprString1 : exprBoolean1; // union //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condAny ? exprAny1 : exprAny2; @@ -41,15 +44,20 @@ var resultIsBoolean1 = condAny ? exprBoolean1 : exprBoolean2; var resultIsNumber1 = condAny ? exprNumber1 : exprNumber2; var resultIsString1 = condAny ? exprString1 : exprString2; var resultIsObject1 = condAny ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean1 = condAny ? exprString1 : exprBoolean1; // union var resultIsAny2 = null ? exprAny1 : exprAny2; var resultIsBoolean2 = null ? exprBoolean1 : exprBoolean2; var resultIsNumber2 = undefined ? exprNumber1 : exprNumber2; var resultIsString2 = [null, undefined] ? exprString1 : exprString2; var resultIsObject2 = [null, undefined] ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean2 = null ? exprString1 : exprBoolean1; // union +var resultIsStringOrBoolean3 = undefined ? exprString1 : exprBoolean1; // union +var resultIsStringOrBoolean4 = [null, undefined] ? exprString1 : exprBoolean1; // union var resultIsAny3 = x.doSomeThing() ? exprAny1 : exprAny2; var resultIsBoolean3 = x("x") ? exprBoolean1 : exprBoolean2; var resultIsNumber3 = x(x) ? exprNumber1 : exprNumber2; var resultIsString3 = x("x") ? exprString1 : exprString2; var resultIsObject3 = x.doSomeThing() ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean5 = x.doSomeThing() ? exprString1 : exprBoolean1; // union \ No newline at end of file diff --git a/tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorConditoinIsStringType.ts b/tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorConditoinIsStringType.ts index 37fd9102922..e8f026d52e3 100644 --- a/tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorConditoinIsStringType.ts +++ b/tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorConditoinIsStringType.ts @@ -19,6 +19,7 @@ condString ? exprBoolean1 : exprBoolean2; condString ? exprNumber1 : exprNumber2; condString ? exprString1 : exprString2; condString ? exprIsObject1 : exprIsObject2; +condString ? exprString1 : exprBoolean1; // union //Cond is a string type literal "" ? exprAny1 : exprAny2; @@ -26,6 +27,7 @@ condString ? exprIsObject1 : exprIsObject2; 'c' ? exprNumber1 : exprNumber2; 'string' ? exprString1 : exprString2; " " ? exprIsObject1 : exprIsObject2; +"hello " ? exprString1 : exprBoolean1; // union //Cond is a string type expression function foo() { return "string" }; @@ -36,6 +38,7 @@ condString.toUpperCase ? exprBoolean1 : exprBoolean2; condString + "string" ? exprNumber1 : exprNumber2; foo() ? exprString1 : exprString2; array[1] ? exprIsObject1 : exprIsObject2; +foo() ? exprString1 : exprBoolean1; // union //Results shoud be same as Expr1 and Expr2 var resultIsAny1 = condString ? exprAny1 : exprAny2; @@ -43,15 +46,19 @@ var resultIsBoolean1 = condString ? exprBoolean1 : exprBoolean2; var resultIsNumber1 = condString ? exprNumber1 : exprNumber2; var resultIsString1 = condString ? exprString1 : exprString2; var resultIsObject1 = condString ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean1 = condString ? exprString1 : exprBoolean1; // union var resultIsAny2 = "" ? exprAny1 : exprAny2; var resultIsBoolean2 = "string" ? exprBoolean1 : exprBoolean2; var resultIsNumber2 = 'c' ? exprNumber1 : exprNumber2; var resultIsString2 = 'string' ? exprString1 : exprString2; var resultIsObject2 = " " ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean2 = "hello" ? exprString1 : exprBoolean1; // union var resultIsAny3 = typeof condString ? exprAny1 : exprAny2; var resultIsBoolean3 = condString.toUpperCase ? exprBoolean1 : exprBoolean2; var resultIsNumber3 = condString + "string" ? exprNumber1 : exprNumber2; var resultIsString3 = foo() ? exprString1 : exprString2; var resultIsObject3 = array[1] ? exprIsObject1 : exprIsObject2; +var resultIsStringOrBoolean3 = typeof condString ? exprString1 : exprBoolean1; // union +var resultIsStringOrBoolean4 = condString.toUpperCase ? exprString1 : exprBoolean1; // union \ No newline at end of file diff --git a/tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorWithoutIdenticalBCT.ts b/tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorWithoutIdenticalBCT.ts index feaa3c5a280..f529b4fb9a0 100644 --- a/tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorWithoutIdenticalBCT.ts +++ b/tests/cases/conformance/expressions/conditonalOperator/conditionalOperatorWithoutIdenticalBCT.ts @@ -14,7 +14,9 @@ var result1 = true ? a : b; //Be contextually typed and and bct is not identical, results in errors that union type is not assignable to target var result2: A = true ? a : b; var result3: B = true ? a : b; +var result31: A | B = true ? a : b; var result4: (t: X) => number = true ? (m) => m.propertyX1 : (n) => n.propertyX2; var result5: (t: X) => string = true ? (m) => m.propertyX1 : (n) => n.propertyX2; -var result6: (t: X) => boolean = true ? (m) => m.propertyX1 : (n) => n.propertyX2; \ No newline at end of file +var result6: (t: X) => boolean = true ? (m) => m.propertyX1 : (n) => n.propertyX2; +var result61: (t: X) => number| string = true ? (m) => m.propertyX1 : (n) => n.propertyX2; From 16fc7a22e23775a52fa1d152f217bc54eab1907e Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 3 Nov 2014 16:42:04 -0800 Subject: [PATCH 12/15] Tests for union type literals A union type literal is written as a sequence of types separated by vertical bars. UnionType: PrimaryOrUnionType | PrimaryType A union typle literal references a union type. When function or constructor types are included in union types they must be enclosed in parentheses --- .../baselines/reference/unionTypeLiterals.js | 29 ++++++++++++++++ .../reference/unionTypeLiterals.types | 34 +++++++++++++++++++ .../typeLiterals/unionTypeLiterals.ts | 15 ++++++++ 3 files changed, 78 insertions(+) create mode 100644 tests/baselines/reference/unionTypeLiterals.js create mode 100644 tests/baselines/reference/unionTypeLiterals.types create mode 100644 tests/cases/conformance/types/specifyingTypes/typeLiterals/unionTypeLiterals.ts diff --git a/tests/baselines/reference/unionTypeLiterals.js b/tests/baselines/reference/unionTypeLiterals.js new file mode 100644 index 00000000000..3e23d47d152 --- /dev/null +++ b/tests/baselines/reference/unionTypeLiterals.js @@ -0,0 +1,29 @@ +//// [unionTypeLiterals.ts] +// basic valid forms of union literals + +var simpleUnion: string | number; +var unionOfUnion: string | number | boolean; + +var arrayOfUnions: (string | number)[]; +var arrayOfUnions: Array; + +var unionOfFunctionType: (() => string) | (() => number); +var unionOfFunctionType: { (): string } | { (): number }; +var unionOfFunctionType: () => string | number; + +var unionOfConstructorType: (new () => string) | (new () => number); +var unionOfConstructorType: { new (): string } | { new (): number }; +var unionOfConstructorType: new () => string | number; + +//// [unionTypeLiterals.js] +// basic valid forms of union literals +var simpleUnion; +var unionOfUnion; +var arrayOfUnions; +var arrayOfUnions; +var unionOfFunctionType; +var unionOfFunctionType; +var unionOfFunctionType; +var unionOfConstructorType; +var unionOfConstructorType; +var unionOfConstructorType; diff --git a/tests/baselines/reference/unionTypeLiterals.types b/tests/baselines/reference/unionTypeLiterals.types new file mode 100644 index 00000000000..90bc4649aa7 --- /dev/null +++ b/tests/baselines/reference/unionTypeLiterals.types @@ -0,0 +1,34 @@ +=== tests/cases/conformance/types/specifyingTypes/typeLiterals/unionTypeLiterals.ts === +// basic valid forms of union literals + +var simpleUnion: string | number; +>simpleUnion : string | number + +var unionOfUnion: string | number | boolean; +>unionOfUnion : string | number | boolean + +var arrayOfUnions: (string | number)[]; +>arrayOfUnions : (string | number)[] + +var arrayOfUnions: Array; +>arrayOfUnions : (string | number)[] +>Array : T[] + +var unionOfFunctionType: (() => string) | (() => number); +>unionOfFunctionType : (() => string) | (() => number) + +var unionOfFunctionType: { (): string } | { (): number }; +>unionOfFunctionType : (() => string) | (() => number) + +var unionOfFunctionType: () => string | number; +>unionOfFunctionType : (() => string) | (() => number) + +var unionOfConstructorType: (new () => string) | (new () => number); +>unionOfConstructorType : (new () => string) | (new () => number) + +var unionOfConstructorType: { new (): string } | { new (): number }; +>unionOfConstructorType : (new () => string) | (new () => number) + +var unionOfConstructorType: new () => string | number; +>unionOfConstructorType : (new () => string) | (new () => number) + diff --git a/tests/cases/conformance/types/specifyingTypes/typeLiterals/unionTypeLiterals.ts b/tests/cases/conformance/types/specifyingTypes/typeLiterals/unionTypeLiterals.ts new file mode 100644 index 00000000000..7d52182beb3 --- /dev/null +++ b/tests/cases/conformance/types/specifyingTypes/typeLiterals/unionTypeLiterals.ts @@ -0,0 +1,15 @@ +// basic valid forms of union literals + +var simpleUnion: string | number; +var unionOfUnion: string | number | boolean; + +var arrayOfUnions: (string | number)[]; +var arrayOfUnions: Array; + +var unionOfFunctionType: (() => string) | (() => number); +var unionOfFunctionType: { (): string } | { (): number }; +var unionOfFunctionType: () => string | number; + +var unionOfConstructorType: (new () => string) | (new () => number); +var unionOfConstructorType: { new (): string } | { new (): number }; +var unionOfConstructorType: new () => string | number; \ No newline at end of file From 1ca9273f49753e864b3a20095feef66d369f1f3d Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Mon, 3 Nov 2014 16:54:00 -0800 Subject: [PATCH 13/15] Identity of union type --- .../reference/unionTypeIdentity.errors.txt | 20 +++++++++++++++++++ .../baselines/reference/unionTypeIdentity.js | 19 ++++++++++++++++++ .../unionTypeIdentity.ts | 8 ++++++++ 3 files changed, 47 insertions(+) create mode 100644 tests/baselines/reference/unionTypeIdentity.errors.txt create mode 100644 tests/baselines/reference/unionTypeIdentity.js create mode 100644 tests/cases/conformance/types/typeRelationships/typeAndMemberIdentity/unionTypeIdentity.ts diff --git a/tests/baselines/reference/unionTypeIdentity.errors.txt b/tests/baselines/reference/unionTypeIdentity.errors.txt new file mode 100644 index 00000000000..77d25bd78d1 --- /dev/null +++ b/tests/baselines/reference/unionTypeIdentity.errors.txt @@ -0,0 +1,20 @@ +tests/cases/conformance/types/typeRelationships/typeAndMemberIdentity/unionTypeIdentity.ts(6,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'strOrNum' must be of type 'string | boolean', but here has type 'string'. +tests/cases/conformance/types/typeRelationships/typeAndMemberIdentity/unionTypeIdentity.ts(7,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'strOrNum' must be of type 'string | boolean', but here has type 'boolean'. +tests/cases/conformance/types/typeRelationships/typeAndMemberIdentity/unionTypeIdentity.ts(8,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'strOrNum' must be of type 'string | boolean', but here has type 'number'. + + +==== tests/cases/conformance/types/typeRelationships/typeAndMemberIdentity/unionTypeIdentity.ts (3 errors) ==== + // Two types are considered identical when + // they are union types with identical sets of constituent types, or + var strOrNum: string | boolean; + var strOrNum: boolean | string; + var strOrNum: boolean | string | boolean; + var strOrNum: string; // error + ~~~~~~~~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'strOrNum' must be of type 'string | boolean', but here has type 'string'. + var strOrNum: boolean; // error + ~~~~~~~~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'strOrNum' must be of type 'string | boolean', but here has type 'boolean'. + var strOrNum: number; // error + ~~~~~~~~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'strOrNum' must be of type 'string | boolean', but here has type 'number'. \ No newline at end of file diff --git a/tests/baselines/reference/unionTypeIdentity.js b/tests/baselines/reference/unionTypeIdentity.js new file mode 100644 index 00000000000..82cad827979 --- /dev/null +++ b/tests/baselines/reference/unionTypeIdentity.js @@ -0,0 +1,19 @@ +//// [unionTypeIdentity.ts] +// Two types are considered identical when +// they are union types with identical sets of constituent types, or +var strOrNum: string | boolean; +var strOrNum: boolean | string; +var strOrNum: boolean | string | boolean; +var strOrNum: string; // error +var strOrNum: boolean; // error +var strOrNum: number; // error + +//// [unionTypeIdentity.js] +// Two types are considered identical when +// they are union types with identical sets of constituent types, or +var strOrNum; +var strOrNum; +var strOrNum; +var strOrNum; // error +var strOrNum; // error +var strOrNum; // error diff --git a/tests/cases/conformance/types/typeRelationships/typeAndMemberIdentity/unionTypeIdentity.ts b/tests/cases/conformance/types/typeRelationships/typeAndMemberIdentity/unionTypeIdentity.ts new file mode 100644 index 00000000000..79100f476bc --- /dev/null +++ b/tests/cases/conformance/types/typeRelationships/typeAndMemberIdentity/unionTypeIdentity.ts @@ -0,0 +1,8 @@ +// Two types are considered identical when +// they are union types with identical sets of constituent types, or +var strOrNum: string | boolean; +var strOrNum: boolean | string; +var strOrNum: boolean | string | boolean; +var strOrNum: string; // error +var strOrNum: boolean; // error +var strOrNum: number; // error \ No newline at end of file From 40af15c8ffc0bc805aff2f6ebf8a7a596013ecb7 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 4 Nov 2014 15:58:44 -0800 Subject: [PATCH 14/15] Array literal produces union type if the it is not contextually typed --- .../reference/unionTypeFromArrayLiteral.js | 79 +++++++++++++++++ .../reference/unionTypeFromArrayLiteral.types | 87 +++++++++++++++++++ .../types/union/unionTypeFromArrayLiteral.ts | 23 +++++ 3 files changed, 189 insertions(+) create mode 100644 tests/baselines/reference/unionTypeFromArrayLiteral.js create mode 100644 tests/baselines/reference/unionTypeFromArrayLiteral.types create mode 100644 tests/cases/conformance/types/union/unionTypeFromArrayLiteral.ts diff --git a/tests/baselines/reference/unionTypeFromArrayLiteral.js b/tests/baselines/reference/unionTypeFromArrayLiteral.js new file mode 100644 index 00000000000..e0410a65229 --- /dev/null +++ b/tests/baselines/reference/unionTypeFromArrayLiteral.js @@ -0,0 +1,79 @@ +//// [unionTypeFromArrayLiteral.ts] +// The resulting type an array literal expression is determined as follows: +// If the array literal is empty, the resulting type is an array type with the element type Undefined. +// Otherwise, if the array literal is contextually typed by a type that has a property with the numeric name ‘0’, the resulting type is a tuple type constructed from the types of the element expressions. +// Otherwise, the resulting type is an array type with an element type that is the union of the types of the element expressions. + +var arr1 = [1, 2]; // number[] +var arr2 = ["hello", true]; // (string | number)[] +var arr3Tuple: [number, string] = [3, "three"]; // [number, string] +var arr4Tuple: [number, string] = [3, "three", "hello"]; // [number, string, string] +var arrEmpty = []; +var arr5Tuple: { + 0: string; + 5: number; +} = ["hello", true, false, " hello", true, 10, "any"]; // Tuple +class C { foo() { } } +class D { foo2() { } } +class E extends C { foo3() { } } +class F extends C { foo4() { } } +var c: C, d: D, e: E, f: F; +var arr6 = [c, d]; // (C | D)[] +var arr7 = [c, d, e]; // (C | D)[] +var arr8 = [c, e]; // C[] +var arr9 = [e, f]; // (E|F)[] + +//// [unionTypeFromArrayLiteral.js] +// The resulting type an array literal expression is determined as follows: +// If the array literal is empty, the resulting type is an array type with the element type Undefined. +// Otherwise, if the array literal is contextually typed by a type that has a property with the numeric name ‘0’, the resulting type is a tuple type constructed from the types of the element expressions. +// Otherwise, the resulting type is an array type with an element type that is the union of the types of the element expressions. +var __extends = this.__extends || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + __.prototype = b.prototype; + d.prototype = new __(); +}; +var arr1 = [1, 2]; // number[] +var arr2 = ["hello", true]; // (string | number)[] +var arr3Tuple = [3, "three"]; // [number, string] +var arr4Tuple = [3, "three", "hello"]; // [number, string, string] +var arrEmpty = []; +var arr5Tuple = ["hello", true, false, " hello", true, 10, "any"]; // Tuple +var C = (function () { + function C() { + } + C.prototype.foo = function () { + }; + return C; +})(); +var D = (function () { + function D() { + } + D.prototype.foo2 = function () { + }; + return D; +})(); +var E = (function (_super) { + __extends(E, _super); + function E() { + _super.apply(this, arguments); + } + E.prototype.foo3 = function () { + }; + return E; +})(C); +var F = (function (_super) { + __extends(F, _super); + function F() { + _super.apply(this, arguments); + } + F.prototype.foo4 = function () { + }; + return F; +})(C); +var c, d, e, f; +var arr6 = [c, d]; // (C | D)[] +var arr7 = [c, d, e]; // (C | D)[] +var arr8 = [c, e]; // C[] +var arr9 = [e, f]; // (E|F)[] diff --git a/tests/baselines/reference/unionTypeFromArrayLiteral.types b/tests/baselines/reference/unionTypeFromArrayLiteral.types new file mode 100644 index 00000000000..7cb09b3ce6a --- /dev/null +++ b/tests/baselines/reference/unionTypeFromArrayLiteral.types @@ -0,0 +1,87 @@ +=== tests/cases/conformance/types/union/unionTypeFromArrayLiteral.ts === +// The resulting type an array literal expression is determined as follows: +// If the array literal is empty, the resulting type is an array type with the element type Undefined. +// Otherwise, if the array literal is contextually typed by a type that has a property with the numeric name ‘0’, the resulting type is a tuple type constructed from the types of the element expressions. +// Otherwise, the resulting type is an array type with an element type that is the union of the types of the element expressions. + +var arr1 = [1, 2]; // number[] +>arr1 : number[] +>[1, 2] : number[] + +var arr2 = ["hello", true]; // (string | number)[] +>arr2 : (string | boolean)[] +>["hello", true] : (string | boolean)[] + +var arr3Tuple: [number, string] = [3, "three"]; // [number, string] +>arr3Tuple : [number, string] +>[3, "three"] : [number, string] + +var arr4Tuple: [number, string] = [3, "three", "hello"]; // [number, string, string] +>arr4Tuple : [number, string] +>[3, "three", "hello"] : [number, string, string] + +var arrEmpty = []; +>arrEmpty : any[] +>[] : undefined[] + +var arr5Tuple: { +>arr5Tuple : { 0: string; 5: number; } + + 0: string; + 5: number; +} = ["hello", true, false, " hello", true, 10, "any"]; // Tuple +>["hello", true, false, " hello", true, 10, "any"] : [string, boolean, boolean, string, boolean, number, string] + +class C { foo() { } } +>C : C +>foo : () => void + +class D { foo2() { } } +>D : D +>foo2 : () => void + +class E extends C { foo3() { } } +>E : E +>C : C +>foo3 : () => void + +class F extends C { foo4() { } } +>F : F +>C : C +>foo4 : () => void + +var c: C, d: D, e: E, f: F; +>c : C +>C : C +>d : D +>D : D +>e : E +>E : E +>f : F +>F : F + +var arr6 = [c, d]; // (C | D)[] +>arr6 : (C | D)[] +>[c, d] : (C | D)[] +>c : C +>d : D + +var arr7 = [c, d, e]; // (C | D)[] +>arr7 : (C | D)[] +>[c, d, e] : (C | D)[] +>c : C +>d : D +>e : E + +var arr8 = [c, e]; // C[] +>arr8 : C[] +>[c, e] : C[] +>c : C +>e : E + +var arr9 = [e, f]; // (E|F)[] +>arr9 : (E | F)[] +>[e, f] : (E | F)[] +>e : E +>f : F + diff --git a/tests/cases/conformance/types/union/unionTypeFromArrayLiteral.ts b/tests/cases/conformance/types/union/unionTypeFromArrayLiteral.ts new file mode 100644 index 00000000000..c6b57584673 --- /dev/null +++ b/tests/cases/conformance/types/union/unionTypeFromArrayLiteral.ts @@ -0,0 +1,23 @@ +// The resulting type an array literal expression is determined as follows: +// If the array literal is empty, the resulting type is an array type with the element type Undefined. +// Otherwise, if the array literal is contextually typed by a type that has a property with the numeric name ‘0’, the resulting type is a tuple type constructed from the types of the element expressions. +// Otherwise, the resulting type is an array type with an element type that is the union of the types of the element expressions. + +var arr1 = [1, 2]; // number[] +var arr2 = ["hello", true]; // (string | number)[] +var arr3Tuple: [number, string] = [3, "three"]; // [number, string] +var arr4Tuple: [number, string] = [3, "three", "hello"]; // [number, string, string] +var arrEmpty = []; +var arr5Tuple: { + 0: string; + 5: number; +} = ["hello", true, false, " hello", true, 10, "any"]; // Tuple +class C { foo() { } } +class D { foo2() { } } +class E extends C { foo3() { } } +class F extends C { foo4() { } } +var c: C, d: D, e: E, f: F; +var arr6 = [c, d]; // (C | D)[] +var arr7 = [c, d, e]; // (C | D)[] +var arr8 = [c, e]; // C[] +var arr9 = [e, f]; // (E|F)[] \ No newline at end of file From 9d31631fd716faf7e4ea6b6e60d8cdbaa451618b Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 4 Nov 2014 16:40:56 -0800 Subject: [PATCH 15/15] Test cases of function infering return type of functions if f is a contextually typed function expression (section 4.9.3), the inferred return type is the union type (section 3.3.4) of the types of the return statement expressions in the function body, ignoring return statements with no expressions. Otherwise, the inferred return type is the first of the types of the return statement expressions in the function body that is a supertype (section 3.8.3) of each of the others, ignoring return statements with no expressions. A compile-time error occurs if no return statement expression has a type that is a supertype of each of the others. --- .../functionImplementationErrors.errors.txt | 67 ++++++++++- .../reference/functionImplementationErrors.js | 83 ++++++++++++++ .../reference/functionImplementations.js | 85 +++++++++++++- .../reference/functionImplementations.types | 105 ++++++++++++++++++ .../functions/functionImplementationErrors.ts | 29 +++++ .../functions/functionImplementations.ts | 37 +++++- 6 files changed, 400 insertions(+), 6 deletions(-) diff --git a/tests/baselines/reference/functionImplementationErrors.errors.txt b/tests/baselines/reference/functionImplementationErrors.errors.txt index fbae17a609d..8ebd5aa272d 100644 --- a/tests/baselines/reference/functionImplementationErrors.errors.txt +++ b/tests/baselines/reference/functionImplementationErrors.errors.txt @@ -6,9 +6,15 @@ tests/cases/conformance/functions/functionImplementationErrors.ts(25,16): error tests/cases/conformance/functions/functionImplementationErrors.ts(30,17): error TS2373: Initializer of parameter 'n' cannot reference identifier 'm' declared after it. tests/cases/conformance/functions/functionImplementationErrors.ts(35,17): error TS2373: Initializer of parameter 'n' cannot reference identifier 'm' declared after it. tests/cases/conformance/functions/functionImplementationErrors.ts(40,28): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement. +tests/cases/conformance/functions/functionImplementationErrors.ts(49,1): error TS2354: No best common type exists among return expressions. +tests/cases/conformance/functions/functionImplementationErrors.ts(53,10): error TS2354: No best common type exists among return expressions. +tests/cases/conformance/functions/functionImplementationErrors.ts(57,11): error TS2354: No best common type exists among return expressions. +tests/cases/conformance/functions/functionImplementationErrors.ts(61,1): error TS2354: No best common type exists among return expressions. +tests/cases/conformance/functions/functionImplementationErrors.ts(65,11): error TS2354: No best common type exists among return expressions. +tests/cases/conformance/functions/functionImplementationErrors.ts(69,11): error TS2354: No best common type exists among return expressions. -==== tests/cases/conformance/functions/functionImplementationErrors.ts (8 errors) ==== +==== tests/cases/conformance/functions/functionImplementationErrors.ts (14 errors) ==== // FunctionExpression with no return type annotation with multiple return statements with unrelated types var f1 = function () { ~~~~~~~~~~~~~ @@ -83,4 +89,63 @@ tests/cases/conformance/functions/functionImplementationErrors.ts(40,28): error throw undefined; var x = 4; }; + + class Base { private x; } + class AnotherClass { private y; } + class Derived1 extends Base { private m; } + class Derived2 extends Base { private n; } + function f8() { + ~~~~~~~~~~~~~~~ + return new Derived1(); + ~~~~~~~~~~~~~~~~~~~~~~~~~~ + return new Derived2(); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + } + ~ +!!! error TS2354: No best common type exists among return expressions. + var f9 = function () { + ~~~~~~~~~~~~~ + return new Derived1(); + ~~~~~~~~~~~~~~~~~~~~~~~~~~ + return new Derived2(); + ~~~~~~~~~~~~~~~~~~~~~~~~~~ + }; + ~ +!!! error TS2354: No best common type exists among return expressions. + var f10 = () => { + ~~~~~~~ + return new Derived1(); + ~~~~~~~~~~~~~~~~~~~~~~~~~~ + return new Derived2(); + ~~~~~~~~~~~~~~~~~~~~~~~~~~ + }; + ~ +!!! error TS2354: No best common type exists among return expressions. + function f11() { + ~~~~~~~~~~~~~~~~ + return new Base(); + ~~~~~~~~~~~~~~~~~~~~~~ + return new AnotherClass(); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + } + ~ +!!! error TS2354: No best common type exists among return expressions. + var f12 = function () { + ~~~~~~~~~~~~~ + return new Base(); + ~~~~~~~~~~~~~~~~~~~~~~ + return new AnotherClass(); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + }; + ~ +!!! error TS2354: No best common type exists among return expressions. + var f13 = () => { + ~~~~~~~ + return new Base(); + ~~~~~~~~~~~~~~~~~~~~~~ + return new AnotherClass(); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + }; + ~ +!!! error TS2354: No best common type exists among return expressions. \ No newline at end of file diff --git a/tests/baselines/reference/functionImplementationErrors.js b/tests/baselines/reference/functionImplementationErrors.js index 90e1997f396..5eaf9027335 100644 --- a/tests/baselines/reference/functionImplementationErrors.js +++ b/tests/baselines/reference/functionImplementationErrors.js @@ -42,9 +42,44 @@ undefined === function (): number { throw undefined; var x = 4; }; + +class Base { private x; } +class AnotherClass { private y; } +class Derived1 extends Base { private m; } +class Derived2 extends Base { private n; } +function f8() { + return new Derived1(); + return new Derived2(); +} +var f9 = function () { + return new Derived1(); + return new Derived2(); +}; +var f10 = () => { + return new Derived1(); + return new Derived2(); +}; +function f11() { + return new Base(); + return new AnotherClass(); +} +var f12 = function () { + return new Base(); + return new AnotherClass(); +}; +var f13 = () => { + return new Base(); + return new AnotherClass(); +}; //// [functionImplementationErrors.js] +var __extends = this.__extends || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + __.prototype = b.prototype; + d.prototype = new __(); +}; // FunctionExpression with no return type annotation with multiple return statements with unrelated types var f1 = function () { return ''; @@ -86,3 +121,51 @@ undefined === function () { throw undefined; var x = 4; }; +var Base = (function () { + function Base() { + } + return Base; +})(); +var AnotherClass = (function () { + function AnotherClass() { + } + return AnotherClass; +})(); +var Derived1 = (function (_super) { + __extends(Derived1, _super); + function Derived1() { + _super.apply(this, arguments); + } + return Derived1; +})(Base); +var Derived2 = (function (_super) { + __extends(Derived2, _super); + function Derived2() { + _super.apply(this, arguments); + } + return Derived2; +})(Base); +function f8() { + return new Derived1(); + return new Derived2(); +} +var f9 = function () { + return new Derived1(); + return new Derived2(); +}; +var f10 = function () { + return new Derived1(); + return new Derived2(); +}; +function f11() { + return new Base(); + return new AnotherClass(); +} +var f12 = function () { + return new Base(); + return new AnotherClass(); +}; +var f13 = function () { + return new Base(); + return new AnotherClass(); +}; diff --git a/tests/baselines/reference/functionImplementations.js b/tests/baselines/reference/functionImplementations.js index 365ee1d7c0d..7c7b753a880 100644 --- a/tests/baselines/reference/functionImplementations.js +++ b/tests/baselines/reference/functionImplementations.js @@ -70,6 +70,10 @@ var n = function () { return 5; }(); +// Otherwise, the inferred return type is the first of the types of the return statement expressions +// in the function body that is a supertype of each of the others, +// ignoring return statements with no expressions. +// A compile - time error occurs if no return statement expression has a type that is a supertype of each of the others. // FunctionExpression with no return type annotation with multiple return statements with subtype relation between returns class Base { private m; } class Derived extends Base { private q; } @@ -120,9 +124,37 @@ function f6(): number { return; } - - - +class Derived2 extends Base { private r: string; } +class AnotherClass { private x } +// if f is a contextually typed function expression, the inferred return type is the union type +// of the types of the return statement expressions in the function body, +// ignoring return statements with no expressions. +var f7: (x: number) => string | number = x => { // should be (x: number) => number | string + if (x < 0) { return x; } + return x.toString(); +} +var f8: (x: number) => any = x => { // should be (x: number) => Base + return new Base(); + return new Derived2(); +} +var f9: (x: number) => any = x => { // should be (x: number) => Base + return new Base(); + return new Derived(); + return new Derived2(); +} +var f10: (x: number) => any = x => { // should be (x: number) => Derived | Derived1 + return new Derived(); + return new Derived2(); +} +var f11: (x: number) => any = x => { // should be (x: number) => Base | AnotherClass + return new Base(); + return new AnotherClass(); +} +var f12: (x: number) => any = x => { // should be (x: number) => Base | AnotherClass + return new Base(); + return; // should be ignored + return new AnotherClass(); +} //// [functionImplementations.js] var __extends = this.__extends || function (d, b) { @@ -192,6 +224,10 @@ var n = function () { return 3; return 5; }(); +// Otherwise, the inferred return type is the first of the types of the return statement expressions +// in the function body that is a supertype of each of the others, +// ignoring return statements with no expressions. +// A compile - time error occurs if no return statement expression has a type that is a supertype of each of the others. // FunctionExpression with no return type annotation with multiple return statements with subtype relation between returns var Base = (function () { function Base() { @@ -249,3 +285,46 @@ function opt3(n, m) { function f6() { return; } +var Derived2 = (function (_super) { + __extends(Derived2, _super); + function Derived2() { + _super.apply(this, arguments); + } + return Derived2; +})(Base); +var AnotherClass = (function () { + function AnotherClass() { + } + return AnotherClass; +})(); +// if f is a contextually typed function expression, the inferred return type is the union type +// of the types of the return statement expressions in the function body, +// ignoring return statements with no expressions. +var f7 = function (x) { + if (x < 0) { + return x; + } + return x.toString(); +}; +var f8 = function (x) { + return new Base(); + return new Derived2(); +}; +var f9 = function (x) { + return new Base(); + return new Derived(); + return new Derived2(); +}; +var f10 = function (x) { + return new Derived(); + return new Derived2(); +}; +var f11 = function (x) { + return new Base(); + return new AnotherClass(); +}; +var f12 = function (x) { + return new Base(); + return; // should be ignored + return new AnotherClass(); +}; diff --git a/tests/baselines/reference/functionImplementations.types b/tests/baselines/reference/functionImplementations.types index 29fe7c0e39c..04144e3a65b 100644 --- a/tests/baselines/reference/functionImplementations.types +++ b/tests/baselines/reference/functionImplementations.types @@ -168,6 +168,10 @@ var n = function () { return 5; }(); +// Otherwise, the inferred return type is the first of the types of the return statement expressions +// in the function body that is a supertype of each of the others, +// ignoring return statements with no expressions. +// A compile - time error occurs if no return statement expression has a type that is a supertype of each of the others. // FunctionExpression with no return type annotation with multiple return statements with subtype relation between returns class Base { private m; } >Base : Base @@ -292,6 +296,107 @@ function f6(): number { return; } +class Derived2 extends Base { private r: string; } +>Derived2 : Derived2 +>Base : Base +>r : string +class AnotherClass { private x } +>AnotherClass : AnotherClass +>x : any +// if f is a contextually typed function expression, the inferred return type is the union type +// of the types of the return statement expressions in the function body, +// ignoring return statements with no expressions. +var f7: (x: number) => string | number = x => { // should be (x: number) => number | string +>f7 : (x: number) => string | number +>x : number +>x => { // should be (x: number) => number | string if (x < 0) { return x; } return x.toString();} : (x: number) => string | number +>x : number + if (x < 0) { return x; } +>x < 0 : boolean +>x : number +>x : number + + return x.toString(); +>x.toString() : string +>x.toString : (radix?: number) => string +>x : number +>toString : (radix?: number) => string +} +var f8: (x: number) => any = x => { // should be (x: number) => Base +>f8 : (x: number) => any +>x : number +>x => { // should be (x: number) => Base return new Base(); return new Derived2();} : (x: number) => Base +>x : number + + return new Base(); +>new Base() : Base +>Base : typeof Base + + return new Derived2(); +>new Derived2() : Derived2 +>Derived2 : typeof Derived2 +} +var f9: (x: number) => any = x => { // should be (x: number) => Base +>f9 : (x: number) => any +>x : number +>x => { // should be (x: number) => Base return new Base(); return new Derived(); return new Derived2();} : (x: number) => Base +>x : number + + return new Base(); +>new Base() : Base +>Base : typeof Base + + return new Derived(); +>new Derived() : Derived +>Derived : typeof Derived + + return new Derived2(); +>new Derived2() : Derived2 +>Derived2 : typeof Derived2 +} +var f10: (x: number) => any = x => { // should be (x: number) => Derived | Derived1 +>f10 : (x: number) => any +>x : number +>x => { // should be (x: number) => Derived | Derived1 return new Derived(); return new Derived2();} : (x: number) => Derived | Derived2 +>x : number + + return new Derived(); +>new Derived() : Derived +>Derived : typeof Derived + + return new Derived2(); +>new Derived2() : Derived2 +>Derived2 : typeof Derived2 +} +var f11: (x: number) => any = x => { // should be (x: number) => Base | AnotherClass +>f11 : (x: number) => any +>x : number +>x => { // should be (x: number) => Base | AnotherClass return new Base(); return new AnotherClass();} : (x: number) => Base | AnotherClass +>x : number + + return new Base(); +>new Base() : Base +>Base : typeof Base + + return new AnotherClass(); +>new AnotherClass() : AnotherClass +>AnotherClass : typeof AnotherClass +} +var f12: (x: number) => any = x => { // should be (x: number) => Base | AnotherClass +>f12 : (x: number) => any +>x : number +>x => { // should be (x: number) => Base | AnotherClass return new Base(); return; // should be ignored return new AnotherClass();} : (x: number) => Base | AnotherClass +>x : number + + return new Base(); +>new Base() : Base +>Base : typeof Base + + return; // should be ignored + return new AnotherClass(); +>new AnotherClass() : AnotherClass +>AnotherClass : typeof AnotherClass +} diff --git a/tests/cases/conformance/functions/functionImplementationErrors.ts b/tests/cases/conformance/functions/functionImplementationErrors.ts index 6db4f6ed7e1..ddd3ba0a2c1 100644 --- a/tests/cases/conformance/functions/functionImplementationErrors.ts +++ b/tests/cases/conformance/functions/functionImplementationErrors.ts @@ -41,3 +41,32 @@ undefined === function (): number { throw undefined; var x = 4; }; + +class Base { private x; } +class AnotherClass { private y; } +class Derived1 extends Base { private m; } +class Derived2 extends Base { private n; } +function f8() { + return new Derived1(); + return new Derived2(); +} +var f9 = function () { + return new Derived1(); + return new Derived2(); +}; +var f10 = () => { + return new Derived1(); + return new Derived2(); +}; +function f11() { + return new Base(); + return new AnotherClass(); +} +var f12 = function () { + return new Base(); + return new AnotherClass(); +}; +var f13 = () => { + return new Base(); + return new AnotherClass(); +}; diff --git a/tests/cases/conformance/functions/functionImplementations.ts b/tests/cases/conformance/functions/functionImplementations.ts index d49b4780772..df36a0b4457 100644 --- a/tests/cases/conformance/functions/functionImplementations.ts +++ b/tests/cases/conformance/functions/functionImplementations.ts @@ -69,6 +69,10 @@ var n = function () { return 5; }(); +// Otherwise, the inferred return type is the first of the types of the return statement expressions +// in the function body that is a supertype of each of the others, +// ignoring return statements with no expressions. +// A compile - time error occurs if no return statement expression has a type that is a supertype of each of the others. // FunctionExpression with no return type annotation with multiple return statements with subtype relation between returns class Base { private m; } class Derived extends Base { private q; } @@ -119,5 +123,34 @@ function f6(): number { return; } - - +class Derived2 extends Base { private r: string; } +class AnotherClass { private x } +// if f is a contextually typed function expression, the inferred return type is the union type +// of the types of the return statement expressions in the function body, +// ignoring return statements with no expressions. +var f7: (x: number) => string | number = x => { // should be (x: number) => number | string + if (x < 0) { return x; } + return x.toString(); +} +var f8: (x: number) => any = x => { // should be (x: number) => Base + return new Base(); + return new Derived2(); +} +var f9: (x: number) => any = x => { // should be (x: number) => Base + return new Base(); + return new Derived(); + return new Derived2(); +} +var f10: (x: number) => any = x => { // should be (x: number) => Derived | Derived1 + return new Derived(); + return new Derived2(); +} +var f11: (x: number) => any = x => { // should be (x: number) => Base | AnotherClass + return new Base(); + return new AnotherClass(); +} +var f12: (x: number) => any = x => { // should be (x: number) => Base | AnotherClass + return new Base(); + return; // should be ignored + return new AnotherClass(); +} \ No newline at end of file