diff --git a/tests/baselines/reference/assignmentCompatBetweenTupleAndArray.errors.txt b/tests/baselines/reference/assignmentCompatBetweenTupleAndArray.errors.txt new file mode 100644 index 0000000000000..7c0a3a5c8b978 --- /dev/null +++ b/tests/baselines/reference/assignmentCompatBetweenTupleAndArray.errors.txt @@ -0,0 +1,36 @@ +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatBetweenTupleAndArray.ts(17,1): error TS2322: Type '[number, string]' is not assignable to type 'number[]': + Types of property 'pop' are incompatible: + Type '() => {}' is not assignable to type '() => number': + Type '{}' is not assignable to type 'number'. +tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatBetweenTupleAndArray.ts(18,1): error TS2322: Type '{}[]' is not assignable to type '[{}]': + Property '0' is missing in type '{}[]'. + + +==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatBetweenTupleAndArray.ts (2 errors) ==== + var numStrTuple: [number, string]; + var numNumTuple: [number, number]; + var numEmptyObjTuple: [number, {}]; + var emptyObjTuple: [{}]; + + var numArray: number[]; + var emptyObjArray: {}[]; + + // no error + numArray = numNumTuple; + emptyObjArray = emptyObjTuple; + emptyObjArray = numStrTuple; + emptyObjArray = numNumTuple; + emptyObjArray = numEmptyObjTuple; + + // error + numArray = numStrTuple; + ~~~~~~~~ +!!! error TS2322: Type '[number, string]' is not assignable to type 'number[]': +!!! error TS2322: Types of property 'pop' are incompatible: +!!! error TS2322: Type '() => {}' is not assignable to type '() => number': +!!! error TS2322: Type '{}' is not assignable to type 'number'. + emptyObjTuple = emptyObjArray; + ~~~~~~~~~~~~~ +!!! error TS2322: Type '{}[]' is not assignable to type '[{}]': +!!! error TS2322: Property '0' is missing in type '{}[]'. + \ No newline at end of file diff --git a/tests/baselines/reference/assignmentCompatBetweenTupleAndArray.js b/tests/baselines/reference/assignmentCompatBetweenTupleAndArray.js new file mode 100644 index 0000000000000..cbe6b1ff04ef6 --- /dev/null +++ b/tests/baselines/reference/assignmentCompatBetweenTupleAndArray.js @@ -0,0 +1,37 @@ +//// [assignmentCompatBetweenTupleAndArray.ts] +var numStrTuple: [number, string]; +var numNumTuple: [number, number]; +var numEmptyObjTuple: [number, {}]; +var emptyObjTuple: [{}]; + +var numArray: number[]; +var emptyObjArray: {}[]; + +// no error +numArray = numNumTuple; +emptyObjArray = emptyObjTuple; +emptyObjArray = numStrTuple; +emptyObjArray = numNumTuple; +emptyObjArray = numEmptyObjTuple; + +// error +numArray = numStrTuple; +emptyObjTuple = emptyObjArray; + + +//// [assignmentCompatBetweenTupleAndArray.js] +var numStrTuple; +var numNumTuple; +var numEmptyObjTuple; +var emptyObjTuple; +var numArray; +var emptyObjArray; +// no error +numArray = numNumTuple; +emptyObjArray = emptyObjTuple; +emptyObjArray = numStrTuple; +emptyObjArray = numNumTuple; +emptyObjArray = numEmptyObjTuple; +// error +numArray = numStrTuple; +emptyObjTuple = emptyObjArray; diff --git a/tests/baselines/reference/bestCommonTypeOfTuple.js b/tests/baselines/reference/bestCommonTypeOfTuple.js new file mode 100644 index 0000000000000..a668b9978b061 --- /dev/null +++ b/tests/baselines/reference/bestCommonTypeOfTuple.js @@ -0,0 +1,58 @@ +//// [bestCommonTypeOfTuple.ts] +function f1(x: number): string { return "foo"; } + +function f2(x: number): number { return 10; } + +function f3(x: number): boolean { return true; } + +enum E1 { one } + +enum E2 { two } + + +var t1: [(x: number) => string, (x: number) => number]; +var t2: [E1, E2]; +var t3: [number, any]; +var t4: [E1, E2, number]; + +// no error +t1 = [f1, f2]; +t2 = [E1.one, E2.two]; +t3 = [5, undefined]; +t4 = [E1.one, E2.two, 20]; +var e1 = t1[2]; // {} +var e2 = t2[2]; // {} +var e3 = t3[2]; // any +var e4 = t4[3]; // number + +//// [bestCommonTypeOfTuple.js] +function f1(x) { + return "foo"; +} +function f2(x) { + return 10; +} +function f3(x) { + return true; +} +var E1; +(function (E1) { + E1[E1["one"] = 0] = "one"; +})(E1 || (E1 = {})); +var E2; +(function (E2) { + E2[E2["two"] = 0] = "two"; +})(E2 || (E2 = {})); +var t1; +var t2; +var t3; +var t4; +// no error +t1 = [f1, f2]; +t2 = [0 /* one */, 0 /* two */]; +t3 = [5, undefined]; +t4 = [0 /* one */, 0 /* two */, 20]; +var e1 = t1[2]; // {} +var e2 = t2[2]; // {} +var e3 = t3[2]; // any +var e4 = t4[3]; // number diff --git a/tests/baselines/reference/bestCommonTypeOfTuple.types b/tests/baselines/reference/bestCommonTypeOfTuple.types new file mode 100644 index 0000000000000..936607769e765 --- /dev/null +++ b/tests/baselines/reference/bestCommonTypeOfTuple.types @@ -0,0 +1,96 @@ +=== tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple.ts === +function f1(x: number): string { return "foo"; } +>f1 : (x: number) => string +>x : number + +function f2(x: number): number { return 10; } +>f2 : (x: number) => number +>x : number + +function f3(x: number): boolean { return true; } +>f3 : (x: number) => boolean +>x : number + +enum E1 { one } +>E1 : E1 +>one : E1 + +enum E2 { two } +>E2 : E2 +>two : E2 + + +var t1: [(x: number) => string, (x: number) => number]; +>t1 : [(x: number) => string, (x: number) => number] +>x : number +>x : number + +var t2: [E1, E2]; +>t2 : [E1, E2] +>E1 : E1 +>E2 : E2 + +var t3: [number, any]; +>t3 : [number, any] + +var t4: [E1, E2, number]; +>t4 : [E1, E2, number] +>E1 : E1 +>E2 : E2 + +// no error +t1 = [f1, f2]; +>t1 = [f1, f2] : [(x: number) => string, (x: number) => number] +>t1 : [(x: number) => string, (x: number) => number] +>[f1, f2] : [(x: number) => string, (x: number) => number] +>f1 : (x: number) => string +>f2 : (x: number) => number + +t2 = [E1.one, E2.two]; +>t2 = [E1.one, E2.two] : [E1, E2] +>t2 : [E1, E2] +>[E1.one, E2.two] : [E1, E2] +>E1.one : E1 +>E1 : typeof E1 +>one : E1 +>E2.two : E2 +>E2 : typeof E2 +>two : E2 + +t3 = [5, undefined]; +>t3 = [5, undefined] : [number, undefined] +>t3 : [number, any] +>[5, undefined] : [number, undefined] +>undefined : undefined + +t4 = [E1.one, E2.two, 20]; +>t4 = [E1.one, E2.two, 20] : [E1, E2, number] +>t4 : [E1, E2, number] +>[E1.one, E2.two, 20] : [E1, E2, number] +>E1.one : E1 +>E1 : typeof E1 +>one : E1 +>E2.two : E2 +>E2 : typeof E2 +>two : E2 + +var e1 = t1[2]; // {} +>e1 : {} +>t1[2] : {} +>t1 : [(x: number) => string, (x: number) => number] + +var e2 = t2[2]; // {} +>e2 : {} +>t2[2] : {} +>t2 : [E1, E2] + +var e3 = t3[2]; // any +>e3 : any +>t3[2] : any +>t3 : [number, any] + +var e4 = t4[3]; // number +>e4 : number +>t4[3] : number +>t4 : [E1, E2, number] + diff --git a/tests/baselines/reference/bestCommonTypeOfTuple2.js b/tests/baselines/reference/bestCommonTypeOfTuple2.js new file mode 100644 index 0000000000000..2f2db308fc9c0 --- /dev/null +++ b/tests/baselines/reference/bestCommonTypeOfTuple2.js @@ -0,0 +1,77 @@ +//// [bestCommonTypeOfTuple2.ts] +interface base { } +interface base1 { i } +class C implements base { c } +class D implements base { d } +class E implements base { e } +class F extends C { f } + +class C1 implements base1 { i = "foo"; c } +class D1 extends C1 { i = "bar"; d } + +var t1: [C, base]; +var t2: [C, D]; +var t3: [C1, D1]; +var t4: [base1, C1]; +var t5: [C1, F] + +var e11 = t1[4]; // base +var e21 = t2[4]; // {} +var e31 = t3[4]; // C1 +var e41 = t4[2]; // base1 +var e51 = t5[2]; // {} + + +//// [bestCommonTypeOfTuple2.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 C = (function () { + function C() { + } + return C; +})(); +var D = (function () { + function D() { + } + return D; +})(); +var E = (function () { + function E() { + } + return E; +})(); +var F = (function (_super) { + __extends(F, _super); + function F() { + _super.apply(this, arguments); + } + return F; +})(C); +var C1 = (function () { + function C1() { + this.i = "foo"; + } + return C1; +})(); +var D1 = (function (_super) { + __extends(D1, _super); + function D1() { + _super.apply(this, arguments); + this.i = "bar"; + } + return D1; +})(C1); +var t1; +var t2; +var t3; +var t4; +var t5; +var e11 = t1[4]; // base +var e21 = t2[4]; // {} +var e31 = t3[4]; // C1 +var e41 = t4[2]; // base1 +var e51 = t5[2]; // {} diff --git a/tests/baselines/reference/bestCommonTypeOfTuple2.types b/tests/baselines/reference/bestCommonTypeOfTuple2.types new file mode 100644 index 0000000000000..ec52e6c685fff --- /dev/null +++ b/tests/baselines/reference/bestCommonTypeOfTuple2.types @@ -0,0 +1,90 @@ +=== tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple2.ts === +interface base { } +>base : base + +interface base1 { i } +>base1 : base1 +>i : any + +class C implements base { c } +>C : C +>base : base +>c : any + +class D implements base { d } +>D : D +>base : base +>d : any + +class E implements base { e } +>E : E +>base : base +>e : any + +class F extends C { f } +>F : F +>C : C +>f : any + +class C1 implements base1 { i = "foo"; c } +>C1 : C1 +>base1 : base1 +>i : string +>c : any + +class D1 extends C1 { i = "bar"; d } +>D1 : D1 +>C1 : C1 +>i : string +>d : any + +var t1: [C, base]; +>t1 : [C, base] +>C : C +>base : base + +var t2: [C, D]; +>t2 : [C, D] +>C : C +>D : D + +var t3: [C1, D1]; +>t3 : [C1, D1] +>C1 : C1 +>D1 : D1 + +var t4: [base1, C1]; +>t4 : [base1, C1] +>base1 : base1 +>C1 : C1 + +var t5: [C1, F] +>t5 : [C1, F] +>C1 : C1 +>F : F + +var e11 = t1[4]; // base +>e11 : base +>t1[4] : base +>t1 : [C, base] + +var e21 = t2[4]; // {} +>e21 : {} +>t2[4] : {} +>t2 : [C, D] + +var e31 = t3[4]; // C1 +>e31 : C1 +>t3[4] : C1 +>t3 : [C1, D1] + +var e41 = t4[2]; // base1 +>e41 : base1 +>t4[2] : base1 +>t4 : [base1, C1] + +var e51 = t5[2]; // {} +>e51 : {} +>t5[2] : {} +>t5 : [C1, F] + diff --git a/tests/baselines/reference/castingTuple.errors.txt b/tests/baselines/reference/castingTuple.errors.txt new file mode 100644 index 0000000000000..ee09362f01f67 --- /dev/null +++ b/tests/baselines/reference/castingTuple.errors.txt @@ -0,0 +1,61 @@ +tests/cases/conformance/types/tuple/castingTuple.ts(24,10): error TS2353: 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 TS2353: 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': + Property 'a' is missing in type 'C'. +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 TS2353: Neither type '[number, string]' nor type 'number[]' is assignable to the other: + Types of property 'pop' are incompatible: + Type '() => {}' is not assignable to type '() => number': + Type '{}' 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 (5 errors) ==== + interface I { } + class A { a = 10; } + class C implements I { c }; + class D implements I { d }; + class E extends A { e }; + class F extends A { f }; + enum E1 { one } + enum E2 { one } + + // no error + var numStrTuple: [number, string] = [5, "foo"]; + var emptyObjTuple = <[{}, {}]>numStrTuple; + var numStrBoolTuple = <[number, string, boolean]>numStrTuple; + 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 t10: [E1, E2] = [E1.one, E2.one]; + var t11 = <[number, number]>t10; + var array1 = <{}[]>emptyObjTuple; + + // error + var t3 = <[number, number]>numStrTuple; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2353: Neither type '[number, string]' nor type '[number, number]' is assignable to the other: +!!! error TS2353: Types of property '1' are incompatible: +!!! error TS2353: Type 'string' is not assignable to type 'number'. + var t9 = <[A, I]>classCDTuple; + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2353: Neither type '[C, D]' nor type '[A, I]' is assignable to the other: +!!! error TS2353: Types of property '0' are incompatible: +!!! error TS2353: Type 'C' is not assignable to type 'A': +!!! error TS2353: Property 'a' is missing in type 'C'. + var array1 = numStrTuple; + ~~~~~~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'array1' must be of type '{}[]', but here has type 'number[]'. + ~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2353: Neither type '[number, string]' nor type 'number[]' is assignable to the other: +!!! error TS2353: Types of property 'pop' are incompatible: +!!! error TS2353: Type '() => {}' is not assignable to type '() => number': +!!! error TS2353: Type '{}' is not assignable to type 'number'. + t4[2] = 10; + ~~ +!!! 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 new file mode 100644 index 0000000000000..c1835e9d117cd --- /dev/null +++ b/tests/baselines/reference/castingTuple.js @@ -0,0 +1,95 @@ +//// [castingTuple.ts] +interface I { } +class A { a = 10; } +class C implements I { c }; +class D implements I { d }; +class E extends A { e }; +class F extends A { f }; +enum E1 { one } +enum E2 { one } + +// no error +var numStrTuple: [number, string] = [5, "foo"]; +var emptyObjTuple = <[{}, {}]>numStrTuple; +var numStrBoolTuple = <[number, string, boolean]>numStrTuple; +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 t10: [E1, E2] = [E1.one, E2.one]; +var t11 = <[number, number]>t10; +var array1 = <{}[]>emptyObjTuple; + +// error +var t3 = <[number, number]>numStrTuple; +var t9 = <[A, I]>classCDTuple; +var array1 = numStrTuple; +t4[2] = 10; + +//// [castingTuple.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 A = (function () { + function A() { + this.a = 10; + } + return A; +})(); +var C = (function () { + function C() { + } + return C; +})(); +; +var D = (function () { + function D() { + } + return D; +})(); +; +var E = (function (_super) { + __extends(E, _super); + function E() { + _super.apply(this, arguments); + } + return E; +})(A); +; +var F = (function (_super) { + __extends(F, _super); + function F() { + _super.apply(this, arguments); + } + return F; +})(A); +; +var E1; +(function (E1) { + E1[E1["one"] = 0] = "one"; +})(E1 || (E1 = {})); +var E2; +(function (E2) { + E2[E2["one"] = 0] = "one"; +})(E2 || (E2 = {})); +// no error +var numStrTuple = [5, "foo"]; +var emptyObjTuple = numStrTuple; +var numStrBoolTuple = numStrTuple; +var classCDTuple = [new C(), new D()]; +var interfaceIITuple = classCDTuple; +var classCDATuple = classCDTuple; +var eleFromCDA1 = classCDATuple[2]; // A +var eleFromCDA2 = classCDATuple[5]; // {} +var t10 = [0 /* one */, 0 /* one */]; +var t11 = t10; +var array1 = emptyObjTuple; +// error +var t3 = numStrTuple; +var t9 = classCDTuple; +var array1 = numStrTuple; +t4[2] = 10; diff --git a/tests/baselines/reference/contextualTypeWithTuple.errors.txt b/tests/baselines/reference/contextualTypeWithTuple.errors.txt new file mode 100644 index 0000000000000..e739c916c8ad5 --- /dev/null +++ b/tests/baselines/reference/contextualTypeWithTuple.errors.txt @@ -0,0 +1,40 @@ +tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts(11,1): error TS2322: 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 TS2322: 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 TS2322: Type '[string, string, number]' is not assignable to type '[string, string]': + Types of property 'pop' are incompatible: + Type '() => {}' is not assignable to type '() => string': + Type '{}' is not assignable to type 'string'. + + +==== tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts (3 errors) ==== + // no error + var numStrTuple: [number, string] = [5, "hello"]; + 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 }]]; + numStrTuple = numStrTuple2; + numStrTuple = numStrBoolTuple; + + // error + objNumTuple = [ {}, 5]; + ~~~~~~~~~~~ +!!! error TS2322: Type '[{}, number]' is not assignable to type '[{ a: string; }, number]': +!!! error TS2322: Types of property '0' are incompatible: +!!! error TS2322: Type '{}' is not assignable to type '{ a: string; }': +!!! error TS2322: Property 'a' is missing in type '{}'. + numStrBoolTuple = numStrTuple; + ~~~~~~~~~~~~~~~ +!!! error TS2322: Type '[number, string]' is not assignable to type '[number, string, boolean]': +!!! error TS2322: Property '2' is missing in type '[number, string]'. + var strStrTuple: [string, string] = ["foo", "bar", 5]; + ~~~~~~~~~~~ +!!! error TS2322: Type '[string, string, number]' is not assignable to type '[string, string]': +!!! error TS2322: Types of property 'pop' are incompatible: +!!! error TS2322: Type '() => {}' is not assignable to type '() => string': +!!! error TS2322: Type '{}' 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 new file mode 100644 index 0000000000000..0e53cea283bdb --- /dev/null +++ b/tests/baselines/reference/contextualTypeWithTuple.js @@ -0,0 +1,29 @@ +//// [contextualTypeWithTuple.ts] +// no error +var numStrTuple: [number, string] = [5, "hello"]; +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 }]]; +numStrTuple = numStrTuple2; +numStrTuple = numStrBoolTuple; + +// error +objNumTuple = [ {}, 5]; +numStrBoolTuple = numStrTuple; +var strStrTuple: [string, string] = ["foo", "bar", 5]; + + +//// [contextualTypeWithTuple.js] +// no error +var numStrTuple = [5, "hello"]; +var numStrTuple2 = [5, "foo", true]; +var numStrBoolTuple = [5, "foo", true]; +var objNumTuple = [{ a: "world" }, 5]; +var strTupleTuple = ["bar", [5, { x: 1, y: 1 }]]; +numStrTuple = numStrTuple2; +numStrTuple = numStrBoolTuple; +// error +objNumTuple = [{}, 5]; +numStrBoolTuple = numStrTuple; +var strStrTuple = ["foo", "bar", 5]; diff --git a/tests/baselines/reference/genericCallWithTupleType.errors.txt b/tests/baselines/reference/genericCallWithTupleType.errors.txt new file mode 100644 index 0000000000000..7f84cee760c07 --- /dev/null +++ b/tests/baselines/reference/genericCallWithTupleType.errors.txt @@ -0,0 +1,47 @@ +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(22,1): error TS2322: Type '[number, string]' is not assignable to type '[string, number]': + Types of property '0' are incompatible: + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(23,1): error TS2322: Type '[{}, {}]' is not assignable to type '[string, number]': + Types of property '0' are incompatible: + Type '{}' is not assignable to type 'string'. +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts(24,1): error TS2322: Type '[{}]' is not assignable to type '[{}, {}]': + Property '1' is missing in type '[{}]'. + + +==== tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts (3 errors) ==== + interface I { + tuple1: [T, U]; + } + + var i1: I; + var i2: I<{}, {}>; + + // no error + i1.tuple1 = ["foo", 5]; + var e1 = i1.tuple1[0]; // string + var e2 = i1.tuple1[1]; // number + i1.tuple1 = ["foo", 5, false, true]; + var e3 = i1.tuple1[2]; // {} + i1.tuple1[3] = { a: "string" }; + var e4 = i1.tuple1[3]; // {} + i2.tuple1 = ["foo", 5]; + i2.tuple1 = ["foo", "bar"]; + i2.tuple1 = [5, "bar"]; + i2.tuple1 = [{}, {}]; + + // error + i1.tuple1 = [5, "foo"]; + ~~~~~~~~~ +!!! error TS2322: Type '[number, string]' is not assignable to type '[string, number]': +!!! error TS2322: Types of property '0' are incompatible: +!!! error TS2322: Type 'number' is not assignable to type 'string'. + i1.tuple1 = [{}, {}]; + ~~~~~~~~~ +!!! error TS2322: Type '[{}, {}]' is not assignable to type '[string, number]': +!!! error TS2322: Types of property '0' are incompatible: +!!! error TS2322: Type '{}' is not assignable to type 'string'. + i2.tuple1 = [{}]; + ~~~~~~~~~ +!!! error TS2322: Type '[{}]' is not assignable to type '[{}, {}]': +!!! error TS2322: Property '1' is missing in type '[{}]'. + \ No newline at end of file diff --git a/tests/baselines/reference/genericCallWithTupleType.js b/tests/baselines/reference/genericCallWithTupleType.js new file mode 100644 index 0000000000000..5ac66f66c3cbc --- /dev/null +++ b/tests/baselines/reference/genericCallWithTupleType.js @@ -0,0 +1,46 @@ +//// [genericCallWithTupleType.ts] +interface I { + tuple1: [T, U]; +} + +var i1: I; +var i2: I<{}, {}>; + +// no error +i1.tuple1 = ["foo", 5]; +var e1 = i1.tuple1[0]; // string +var e2 = i1.tuple1[1]; // number +i1.tuple1 = ["foo", 5, false, true]; +var e3 = i1.tuple1[2]; // {} +i1.tuple1[3] = { a: "string" }; +var e4 = i1.tuple1[3]; // {} +i2.tuple1 = ["foo", 5]; +i2.tuple1 = ["foo", "bar"]; +i2.tuple1 = [5, "bar"]; +i2.tuple1 = [{}, {}]; + +// error +i1.tuple1 = [5, "foo"]; +i1.tuple1 = [{}, {}]; +i2.tuple1 = [{}]; + + +//// [genericCallWithTupleType.js] +var i1; +var i2; +// no error +i1.tuple1 = ["foo", 5]; +var e1 = i1.tuple1[0]; // string +var e2 = i1.tuple1[1]; // number +i1.tuple1 = ["foo", 5, false, true]; +var e3 = i1.tuple1[2]; // {} +i1.tuple1[3] = { a: "string" }; +var e4 = i1.tuple1[3]; // {} +i2.tuple1 = ["foo", 5]; +i2.tuple1 = ["foo", "bar"]; +i2.tuple1 = [5, "bar"]; +i2.tuple1 = [{}, {}]; +// error +i1.tuple1 = [5, "foo"]; +i1.tuple1 = [{}, {}]; +i2.tuple1 = [{}]; diff --git a/tests/baselines/reference/indexerWithTuple.js b/tests/baselines/reference/indexerWithTuple.js new file mode 100644 index 0000000000000..bc3bee9dd1795 --- /dev/null +++ b/tests/baselines/reference/indexerWithTuple.js @@ -0,0 +1,32 @@ +//// [indexerWithTuple.ts] +var strNumTuple: [string, number] = ["foo", 10]; +var numTupleTuple: [number, [string, number]] = [10, ["bar", 20]]; + +// 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 ele15 = strNumTuple["0"]; // string +var ele16 = strNumTuple["1"]; // number +var strNumTuple1 = numTupleTuple[1]; //[string, number]; +var ele17 = numTupleTuple[2]; // {} + +//// [indexerWithTuple.js] +var strNumTuple = ["foo", 10]; +var numTupleTuple = [10, ["bar", 20]]; +// 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 ele15 = strNumTuple["0"]; // string +var ele16 = strNumTuple["1"]; // number +var strNumTuple1 = numTupleTuple[1]; //[string, number]; +var ele17 = numTupleTuple[2]; // {} diff --git a/tests/baselines/reference/indexerWithTuple.types b/tests/baselines/reference/indexerWithTuple.types new file mode 100644 index 0000000000000..7c22cac407fdb --- /dev/null +++ b/tests/baselines/reference/indexerWithTuple.types @@ -0,0 +1,64 @@ +=== tests/cases/conformance/types/tuple/indexerWithTuple.ts === +var strNumTuple: [string, number] = ["foo", 10]; +>strNumTuple : [string, number] +>["foo", 10] : [string, number] + +var numTupleTuple: [number, [string, number]] = [10, ["bar", 20]]; +>numTupleTuple : [number, [string, number]] +>[10, ["bar", 20]] : [number, [string, number]] +>["bar", 20] : [string, number] + +// no error +var idx0 = 0; +>idx0 : number + +var idx1 = 1; +>idx1 : number + +var ele10 = strNumTuple[0]; // string +>ele10 : string +>strNumTuple[0] : string +>strNumTuple : [string, number] + +var ele11 = strNumTuple[1]; // number +>ele11 : number +>strNumTuple[1] : number +>strNumTuple : [string, number] + +var ele12 = strNumTuple[2]; // {} +>ele12 : {} +>strNumTuple[2] : {} +>strNumTuple : [string, number] + +var ele13 = strNumTuple[idx0]; // {} +>ele13 : {} +>strNumTuple[idx0] : {} +>strNumTuple : [string, number] +>idx0 : number + +var ele14 = strNumTuple[idx1]; // {} +>ele14 : {} +>strNumTuple[idx1] : {} +>strNumTuple : [string, number] +>idx1 : number + +var ele15 = strNumTuple["0"]; // string +>ele15 : string +>strNumTuple["0"] : string +>strNumTuple : [string, number] + +var ele16 = strNumTuple["1"]; // number +>ele16 : number +>strNumTuple["1"] : number +>strNumTuple : [string, number] + +var strNumTuple1 = numTupleTuple[1]; //[string, number]; +>strNumTuple1 : [string, number] +>numTupleTuple[1] : [string, number] +>numTupleTuple : [number, [string, number]] + +var ele17 = numTupleTuple[2]; // {} +>ele17 : {} +>numTupleTuple[2] : {} +>numTupleTuple : [number, [string, number]] + diff --git a/tests/baselines/reference/typeInferenceWithTupleType.js b/tests/baselines/reference/typeInferenceWithTupleType.js new file mode 100644 index 0000000000000..a9d75ad9990c8 --- /dev/null +++ b/tests/baselines/reference/typeInferenceWithTupleType.js @@ -0,0 +1,48 @@ +//// [typeInferenceWithTupleType.ts] +function combine(x: T, y: U): [T, U] { + return [x, y]; +} + +var combineResult = combine("string", 10); +var combineEle1 = combineResult[0]; // string +var combineEle2 = combineResult[1]; // number + +function zip(array1: T[], array2: U[]): [[T, U]] { + if (array1.length != array2.length) { + return [[undefined, undefined]]; + } + var length = array1.length; + var zipResult: [[T, U]]; + for (var i = 0; i < length; ++i) { + zipResult.push([array1[i], array2[i]]); + } + return zipResult; +} + +var zipResult = zip(["foo", "bar"], [5, 6]); +var zipResultEle = zipResult[0]; // [string, number] +var zipResultEleEle = zipResult[0][0]; // string + + + +//// [typeInferenceWithTupleType.js] +function combine(x, y) { + return [x, y]; +} +var combineResult = combine("string", 10); +var combineEle1 = combineResult[0]; // string +var combineEle2 = combineResult[1]; // number +function zip(array1, array2) { + if (array1.length != array2.length) { + return [[undefined, undefined]]; + } + var length = array1.length; + var zipResult; + for (var i = 0; i < length; ++i) { + zipResult.push([array1[i], array2[i]]); + } + return zipResult; +} +var zipResult = zip(["foo", "bar"], [5, 6]); +var zipResultEle = zipResult[0]; // [string, number] +var zipResultEleEle = zipResult[0][0]; // string diff --git a/tests/baselines/reference/typeInferenceWithTupleType.types b/tests/baselines/reference/typeInferenceWithTupleType.types new file mode 100644 index 0000000000000..fbf1cd51920a7 --- /dev/null +++ b/tests/baselines/reference/typeInferenceWithTupleType.types @@ -0,0 +1,114 @@ +=== tests/cases/conformance/types/tuple/typeInferenceWithTupleType.ts === +function combine(x: T, y: U): [T, U] { +>combine : (x: T, y: U) => [T, U] +>T : T +>U : U +>x : T +>T : T +>y : U +>U : U +>T : T +>U : U + + return [x, y]; +>[x, y] : [T, U] +>x : T +>y : U +} + +var combineResult = combine("string", 10); +>combineResult : [string, number] +>combine("string", 10) : [string, number] +>combine : (x: T, y: U) => [T, U] + +var combineEle1 = combineResult[0]; // string +>combineEle1 : string +>combineResult[0] : string +>combineResult : [string, number] + +var combineEle2 = combineResult[1]; // number +>combineEle2 : number +>combineResult[1] : number +>combineResult : [string, number] + +function zip(array1: T[], array2: U[]): [[T, U]] { +>zip : (array1: T[], array2: U[]) => [[T, U]] +>T : T +>U : U +>array1 : T[] +>T : T +>array2 : U[] +>U : U +>T : T +>U : U + + if (array1.length != array2.length) { +>array1.length != array2.length : boolean +>array1.length : number +>array1 : T[] +>length : number +>array2.length : number +>array2 : U[] +>length : number + + return [[undefined, undefined]]; +>[[undefined, undefined]] : [[undefined, undefined]] +>[undefined, undefined] : [undefined, undefined] +>undefined : undefined +>undefined : undefined + } + var length = array1.length; +>length : number +>array1.length : number +>array1 : T[] +>length : number + + var zipResult: [[T, U]]; +>zipResult : [[T, U]] +>T : T +>U : U + + for (var i = 0; i < length; ++i) { +>i : number +>i < length : boolean +>i : number +>length : number +>++i : number +>i : number + + zipResult.push([array1[i], array2[i]]); +>zipResult.push([array1[i], array2[i]]) : number +>zipResult.push : (...items: [T, U][]) => number +>zipResult : [[T, U]] +>push : (...items: [T, U][]) => number +>[array1[i], array2[i]] : [T, U] +>array1[i] : T +>array1 : T[] +>i : number +>array2[i] : U +>array2 : U[] +>i : number + } + return zipResult; +>zipResult : [[T, U]] +} + +var zipResult = zip(["foo", "bar"], [5, 6]); +>zipResult : [[string, number]] +>zip(["foo", "bar"], [5, 6]) : [[string, number]] +>zip : (array1: T[], array2: U[]) => [[T, U]] +>["foo", "bar"] : string[] +>[5, 6] : number[] + +var zipResultEle = zipResult[0]; // [string, number] +>zipResultEle : [string, number] +>zipResult[0] : [string, number] +>zipResult : [[string, number]] + +var zipResultEleEle = zipResult[0][0]; // string +>zipResultEleEle : string +>zipResult[0][0] : string +>zipResult[0] : [string, number] +>zipResult : [[string, number]] + + diff --git a/tests/cases/conformance/types/tuple/castingTuple.ts b/tests/cases/conformance/types/tuple/castingTuple.ts new file mode 100644 index 0000000000000..f154e5f00c8e8 --- /dev/null +++ b/tests/cases/conformance/types/tuple/castingTuple.ts @@ -0,0 +1,27 @@ +interface I { } +class A { a = 10; } +class C implements I { c }; +class D implements I { d }; +class E extends A { e }; +class F extends A { f }; +enum E1 { one } +enum E2 { one } + +// no error +var numStrTuple: [number, string] = [5, "foo"]; +var emptyObjTuple = <[{}, {}]>numStrTuple; +var numStrBoolTuple = <[number, string, boolean]>numStrTuple; +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 t10: [E1, E2] = [E1.one, E2.one]; +var t11 = <[number, number]>t10; +var array1 = <{}[]>emptyObjTuple; + +// error +var t3 = <[number, number]>numStrTuple; +var t9 = <[A, I]>classCDTuple; +var array1 = numStrTuple; +t4[2] = 10; \ No newline at end of file diff --git a/tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts b/tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts new file mode 100644 index 0000000000000..7e9575d7f82b4 --- /dev/null +++ b/tests/cases/conformance/types/tuple/contextualTypeWithTuple.ts @@ -0,0 +1,13 @@ +// no error +var numStrTuple: [number, string] = [5, "hello"]; +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 }]]; +numStrTuple = numStrTuple2; +numStrTuple = numStrBoolTuple; + +// error +objNumTuple = [ {}, 5]; +numStrBoolTuple = numStrTuple; +var strStrTuple: [string, string] = ["foo", "bar", 5]; diff --git a/tests/cases/conformance/types/tuple/indexerWithTuple.ts b/tests/cases/conformance/types/tuple/indexerWithTuple.ts new file mode 100644 index 0000000000000..0b51ecd32ee53 --- /dev/null +++ b/tests/cases/conformance/types/tuple/indexerWithTuple.ts @@ -0,0 +1,15 @@ +var strNumTuple: [string, number] = ["foo", 10]; +var numTupleTuple: [number, [string, number]] = [10, ["bar", 20]]; + +// 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 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 diff --git a/tests/cases/conformance/types/tuple/typeInferenceWithTupleType.ts b/tests/cases/conformance/types/tuple/typeInferenceWithTupleType.ts new file mode 100644 index 0000000000000..d19353d29ef02 --- /dev/null +++ b/tests/cases/conformance/types/tuple/typeInferenceWithTupleType.ts @@ -0,0 +1,24 @@ +function combine(x: T, y: U): [T, U] { + return [x, y]; +} + +var combineResult = combine("string", 10); +var combineEle1 = combineResult[0]; // string +var combineEle2 = combineResult[1]; // number + +function zip(array1: T[], array2: U[]): [[T, U]] { + if (array1.length != array2.length) { + return [[undefined, undefined]]; + } + var length = array1.length; + var zipResult: [[T, U]]; + for (var i = 0; i < length; ++i) { + zipResult.push([array1[i], array2[i]]); + } + return zipResult; +} + +var zipResult = zip(["foo", "bar"], [5, 6]); +var zipResultEle = zipResult[0]; // [string, number] +var zipResultEleEle = zipResult[0][0]; // string + diff --git a/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatBetweenTupleAndArray.ts b/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatBetweenTupleAndArray.ts new file mode 100644 index 0000000000000..3811809742cc1 --- /dev/null +++ b/tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatBetweenTupleAndArray.ts @@ -0,0 +1,18 @@ +var numStrTuple: [number, string]; +var numNumTuple: [number, number]; +var numEmptyObjTuple: [number, {}]; +var emptyObjTuple: [{}]; + +var numArray: number[]; +var emptyObjArray: {}[]; + +// no error +numArray = numNumTuple; +emptyObjArray = emptyObjTuple; +emptyObjArray = numStrTuple; +emptyObjArray = numNumTuple; +emptyObjArray = numEmptyObjTuple; + +// error +numArray = numStrTuple; +emptyObjTuple = emptyObjArray; diff --git a/tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple.ts b/tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple.ts new file mode 100644 index 0000000000000..6d5aff974eb10 --- /dev/null +++ b/tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple.ts @@ -0,0 +1,25 @@ +function f1(x: number): string { return "foo"; } + +function f2(x: number): number { return 10; } + +function f3(x: number): boolean { return true; } + +enum E1 { one } + +enum E2 { two } + + +var t1: [(x: number) => string, (x: number) => number]; +var t2: [E1, E2]; +var t3: [number, any]; +var t4: [E1, E2, number]; + +// no error +t1 = [f1, f2]; +t2 = [E1.one, E2.two]; +t3 = [5, undefined]; +t4 = [E1.one, E2.two, 20]; +var e1 = t1[2]; // {} +var e2 = t2[2]; // {} +var e3 = t3[2]; // any +var e4 = t4[3]; // number \ No newline at end of file diff --git a/tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple2.ts b/tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple2.ts new file mode 100644 index 0000000000000..e3487f6bee2f7 --- /dev/null +++ b/tests/cases/conformance/types/typeRelationships/bestCommonType/bestCommonTypeOfTuple2.ts @@ -0,0 +1,21 @@ +interface base { } +interface base1 { i } +class C implements base { c } +class D implements base { d } +class E implements base { e } +class F extends C { f } + +class C1 implements base1 { i = "foo"; c } +class D1 extends C1 { i = "bar"; d } + +var t1: [C, base]; +var t2: [C, D]; +var t3: [C1, D1]; +var t4: [base1, C1]; +var t5: [C1, F] + +var e11 = t1[4]; // base +var e21 = t2[4]; // {} +var e31 = t3[4]; // C1 +var e41 = t4[2]; // base1 +var e51 = t5[2]; // {} diff --git a/tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts b/tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts new file mode 100644 index 0000000000000..60198e1c510ba --- /dev/null +++ b/tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithTupleType.ts @@ -0,0 +1,24 @@ +interface I { + tuple1: [T, U]; +} + +var i1: I; +var i2: I<{}, {}>; + +// no error +i1.tuple1 = ["foo", 5]; +var e1 = i1.tuple1[0]; // string +var e2 = i1.tuple1[1]; // number +i1.tuple1 = ["foo", 5, false, true]; +var e3 = i1.tuple1[2]; // {} +i1.tuple1[3] = { a: "string" }; +var e4 = i1.tuple1[3]; // {} +i2.tuple1 = ["foo", 5]; +i2.tuple1 = ["foo", "bar"]; +i2.tuple1 = [5, "bar"]; +i2.tuple1 = [{}, {}]; + +// error +i1.tuple1 = [5, "foo"]; +i1.tuple1 = [{}, {}]; +i2.tuple1 = [{}];