Skip to content

Commit fce012d

Browse files
committed
Merge pull request #2735 from Microsoft/conformanceParameterDecl
Conformance test for Spec Change in Section 3.8.2.2 parameter Declaration and 6.4 Destructuring parameter declarations
2 parents 183c1c4 + 3a15b3f commit fce012d

27 files changed

+3414
-0
lines changed
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts(32,4): error TS2345: Argument of type '[string, number, number]' is not assignable to parameter of type '[undefined, null, undefined]'.
2+
Types of property '0' are incompatible.
3+
Type 'string' is not assignable to type 'undefined'.
4+
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts(33,4): error TS2345: Argument of type '[[string], number, [[boolean, boolean]]]' is not assignable to parameter of type '[[undefined], undefined, [[undefined, undefined]]]'.
5+
Types of property '0' are incompatible.
6+
Type '[string]' is not assignable to type '[undefined]'.
7+
Types of property '0' are incompatible.
8+
Type 'string' is not assignable to type 'undefined'.
9+
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts(62,10): error TS2393: Duplicate function implementation.
10+
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts(63,10): error TS2393: Duplicate function implementation.
11+
12+
13+
==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration1ES5.ts (4 errors) ====
14+
// A parameter declaration may specify either an identifier or a binding pattern.
15+
// The identifiers specified in parameter declarations and binding patterns
16+
// in a parameter list must be unique within that parameter list.
17+
18+
// If the declaration includes a type annotation, the parameter is of that type
19+
function a1([a, b, [[c]]]: [number, number, string[][]]) { }
20+
function a2(o: { x: number, a: number }) { }
21+
function a3({j, k, l: {m, n}, q: [a, b, c]}: { j: number, k: string, l: { m: boolean, n: number }, q: (number|string)[] }) { };
22+
function a4({x, a}: { x: number, a: number }) { }
23+
24+
a1([1, 2, [["world"]]]);
25+
a1([1, 2, [["world"]], 3]);
26+
27+
// If the declaration includes an initializer expression (which is permitted only
28+
// when the parameter list occurs in conjunction with a function body),
29+
// the parameter type is the widened form (section 3.11) of the type of the initializer expression.
30+
31+
function b1(z = [undefined, null]) { };
32+
function b2(z = null, o = { x: 0, y: undefined }) { }
33+
function b3({z: {x, y: {j}}} = { z: { x: "hi", y: { j: 1 } } }) { }
34+
35+
interface F1 {
36+
b5(z, y, [, a, b], {p, m: { q, r}});
37+
}
38+
39+
function b6([a, z, y] = [undefined, null, undefined]) { }
40+
function b7([[a], b, [[c, d]]] = [[undefined], undefined, [[undefined, undefined]]]) { }
41+
42+
b1([1, 2, 3]); // z is widen to the type any[]
43+
b2("string", { x: 200, y: "string" });
44+
b2("string", { x: 200, y: true });
45+
b6(["string", 1, 2]); // Shouldn't be an error
46+
~~~~~~~~~~~~~~~~
47+
!!! error TS2345: Argument of type '[string, number, number]' is not assignable to parameter of type '[undefined, null, undefined]'.
48+
!!! error TS2345: Types of property '0' are incompatible.
49+
!!! error TS2345: Type 'string' is not assignable to type 'undefined'.
50+
b7([["string"], 1, [[true, false]]]); // Shouldn't be an error
51+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
52+
!!! error TS2345: Argument of type '[[string], number, [[boolean, boolean]]]' is not assignable to parameter of type '[[undefined], undefined, [[undefined, undefined]]]'.
53+
!!! error TS2345: Types of property '0' are incompatible.
54+
!!! error TS2345: Type '[string]' is not assignable to type '[undefined]'.
55+
!!! error TS2345: Types of property '0' are incompatible.
56+
!!! error TS2345: Type 'string' is not assignable to type 'undefined'.
57+
58+
59+
// If the declaration specifies a binding pattern, the parameter type is the implied type of that binding pattern (section 5.1.3)
60+
enum Foo { a }
61+
function c0({z: {x, y: {j}}}) { }
62+
function c1({z} = { z: 10 }) { }
63+
function c2({z = 10}) { }
64+
function c3({b}: { b: number|string} = { b: "hello" }) { }
65+
function c5([a, b, [[c]]]) { }
66+
function c6([a, b, [[c=1]]]) { }
67+
68+
c0({z : { x: 1, y: { j: "world" } }}); // Implied type is { z: {x: any, y: {j: any}} }
69+
c0({z : { x: "string", y: { j: true } }}); // Implied type is { z: {x: any, y: {j: any}} }
70+
71+
c1(); // Implied type is {z:number}?
72+
c1({ z: 1 }) // Implied type is {z:number}?
73+
74+
c2({}); // Implied type is {z?: number}
75+
c2({z:1}); // Implied type is {z?: number}
76+
77+
c3({ b: 1 }); // Implied type is { b: number|string }.
78+
79+
c5([1, 2, [["string"]]]); // Implied type is is [any, any, [[any]]]
80+
c5([1, 2, [["string"]], false, true]); // Implied type is is [any, any, [[any]]]
81+
82+
// A parameter can be marked optional by following its name or binding pattern with a question mark (?)
83+
// or by including an initializer.
84+
85+
function d0(x?) { }
86+
~~
87+
!!! error TS2393: Duplicate function implementation.
88+
function d0(x = 10) { }
89+
~~
90+
!!! error TS2393: Duplicate function implementation.
91+
92+
interface F2 {
93+
d3([a, b, c]?);
94+
d4({x, y, z}?);
95+
e0([a, b, c]);
96+
}
97+
98+
class C2 implements F2 {
99+
constructor() { }
100+
d3() { }
101+
d4() { }
102+
e0([a, b, c]) { }
103+
}
104+
105+
class C3 implements F2 {
106+
d3([a, b, c]) { }
107+
d4({x, y, z}) { }
108+
e0([a, b, c]) { }
109+
}
110+
111+
112+
function d5({x, y} = { x: 1, y: 2 }) { }
113+
d5(); // Parameter is optional as its declaration included an initializer
114+
115+
// Destructuring parameter declarations do not permit type annotations on the individual binding patterns,
116+
// as such annotations would conflict with the already established meaning of colons in object literals.
117+
// Type annotations must instead be written on the top- level parameter declaration
118+
119+
function e1({x: number}) { } // x has type any NOT number
120+
function e2({x}: { x: number }) { } // x is type number
121+
function e3({x}: { x?: number }) { } // x is an optional with type number
122+
function e4({x: [number,string,any] }) { } // x has type [any, any, any]
123+
function e5({x: [a, b, c]}: { x: [number, number, number] }) { } // x has type [any, any, any]
124+
Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
//// [destructuringParameterDeclaration1ES5.ts]
2+
// A parameter declaration may specify either an identifier or a binding pattern.
3+
// The identifiers specified in parameter declarations and binding patterns
4+
// in a parameter list must be unique within that parameter list.
5+
6+
// If the declaration includes a type annotation, the parameter is of that type
7+
function a1([a, b, [[c]]]: [number, number, string[][]]) { }
8+
function a2(o: { x: number, a: number }) { }
9+
function a3({j, k, l: {m, n}, q: [a, b, c]}: { j: number, k: string, l: { m: boolean, n: number }, q: (number|string)[] }) { };
10+
function a4({x, a}: { x: number, a: number }) { }
11+
12+
a1([1, 2, [["world"]]]);
13+
a1([1, 2, [["world"]], 3]);
14+
15+
// If the declaration includes an initializer expression (which is permitted only
16+
// when the parameter list occurs in conjunction with a function body),
17+
// the parameter type is the widened form (section 3.11) of the type of the initializer expression.
18+
19+
function b1(z = [undefined, null]) { };
20+
function b2(z = null, o = { x: 0, y: undefined }) { }
21+
function b3({z: {x, y: {j}}} = { z: { x: "hi", y: { j: 1 } } }) { }
22+
23+
interface F1 {
24+
b5(z, y, [, a, b], {p, m: { q, r}});
25+
}
26+
27+
function b6([a, z, y] = [undefined, null, undefined]) { }
28+
function b7([[a], b, [[c, d]]] = [[undefined], undefined, [[undefined, undefined]]]) { }
29+
30+
b1([1, 2, 3]); // z is widen to the type any[]
31+
b2("string", { x: 200, y: "string" });
32+
b2("string", { x: 200, y: true });
33+
b6(["string", 1, 2]); // Shouldn't be an error
34+
b7([["string"], 1, [[true, false]]]); // Shouldn't be an error
35+
36+
37+
// If the declaration specifies a binding pattern, the parameter type is the implied type of that binding pattern (section 5.1.3)
38+
enum Foo { a }
39+
function c0({z: {x, y: {j}}}) { }
40+
function c1({z} = { z: 10 }) { }
41+
function c2({z = 10}) { }
42+
function c3({b}: { b: number|string} = { b: "hello" }) { }
43+
function c5([a, b, [[c]]]) { }
44+
function c6([a, b, [[c=1]]]) { }
45+
46+
c0({z : { x: 1, y: { j: "world" } }}); // Implied type is { z: {x: any, y: {j: any}} }
47+
c0({z : { x: "string", y: { j: true } }}); // Implied type is { z: {x: any, y: {j: any}} }
48+
49+
c1(); // Implied type is {z:number}?
50+
c1({ z: 1 }) // Implied type is {z:number}?
51+
52+
c2({}); // Implied type is {z?: number}
53+
c2({z:1}); // Implied type is {z?: number}
54+
55+
c3({ b: 1 }); // Implied type is { b: number|string }.
56+
57+
c5([1, 2, [["string"]]]); // Implied type is is [any, any, [[any]]]
58+
c5([1, 2, [["string"]], false, true]); // Implied type is is [any, any, [[any]]]
59+
60+
// A parameter can be marked optional by following its name or binding pattern with a question mark (?)
61+
// or by including an initializer.
62+
63+
function d0(x?) { }
64+
function d0(x = 10) { }
65+
66+
interface F2 {
67+
d3([a, b, c]?);
68+
d4({x, y, z}?);
69+
e0([a, b, c]);
70+
}
71+
72+
class C2 implements F2 {
73+
constructor() { }
74+
d3() { }
75+
d4() { }
76+
e0([a, b, c]) { }
77+
}
78+
79+
class C3 implements F2 {
80+
d3([a, b, c]) { }
81+
d4({x, y, z}) { }
82+
e0([a, b, c]) { }
83+
}
84+
85+
86+
function d5({x, y} = { x: 1, y: 2 }) { }
87+
d5(); // Parameter is optional as its declaration included an initializer
88+
89+
// Destructuring parameter declarations do not permit type annotations on the individual binding patterns,
90+
// as such annotations would conflict with the already established meaning of colons in object literals.
91+
// Type annotations must instead be written on the top- level parameter declaration
92+
93+
function e1({x: number}) { } // x has type any NOT number
94+
function e2({x}: { x: number }) { } // x is type number
95+
function e3({x}: { x?: number }) { } // x is an optional with type number
96+
function e4({x: [number,string,any] }) { } // x has type [any, any, any]
97+
function e5({x: [a, b, c]}: { x: [number, number, number] }) { } // x has type [any, any, any]
98+
99+
100+
//// [destructuringParameterDeclaration1ES5.js]
101+
// A parameter declaration may specify either an identifier or a binding pattern.
102+
// The identifiers specified in parameter declarations and binding patterns
103+
// in a parameter list must be unique within that parameter list.
104+
// If the declaration includes a type annotation, the parameter is of that type
105+
function a1(_a) {
106+
var a = _a[0], b = _a[1], c = _a[2][0][0];
107+
}
108+
function a2(o) { }
109+
function a3(_a) {
110+
var j = _a.j, k = _a.k, _b = _a.l, m = _b.m, n = _b.n, _c = _a.q, a = _c[0], b = _c[1], c = _c[2];
111+
}
112+
;
113+
function a4(_a) {
114+
var x = _a.x, a = _a.a;
115+
}
116+
a1([1, 2, [["world"]]]);
117+
a1([1, 2, [["world"]], 3]);
118+
// If the declaration includes an initializer expression (which is permitted only
119+
// when the parameter list occurs in conjunction with a function body),
120+
// the parameter type is the widened form (section 3.11) of the type of the initializer expression.
121+
function b1(z) {
122+
if (z === void 0) { z = [undefined, null]; }
123+
}
124+
;
125+
function b2(z, o) {
126+
if (z === void 0) { z = null; }
127+
if (o === void 0) { o = { x: 0, y: undefined }; }
128+
}
129+
function b3(_a) {
130+
var _b = (_a === void 0 ? { z: { x: "hi", y: { j: 1 } } } : _a).z, x = _b.x, j = _b.y.j;
131+
}
132+
function b6(_a) {
133+
var _b = _a === void 0 ? [undefined, null, undefined] : _a, a = _b[0], z = _b[1], y = _b[2];
134+
}
135+
function b7(_a) {
136+
var _b = _a === void 0 ? [[undefined], undefined, [[undefined, undefined]]] : _a, a = _b[0][0], b = _b[1], _c = _b[2][0], c = _c[0], d = _c[1];
137+
}
138+
b1([1, 2, 3]); // z is widen to the type any[]
139+
b2("string", { x: 200, y: "string" });
140+
b2("string", { x: 200, y: true });
141+
b6(["string", 1, 2]); // Shouldn't be an error
142+
b7([["string"], 1, [[true, false]]]); // Shouldn't be an error
143+
// If the declaration specifies a binding pattern, the parameter type is the implied type of that binding pattern (section 5.1.3)
144+
var Foo;
145+
(function (Foo) {
146+
Foo[Foo["a"] = 0] = "a";
147+
})(Foo || (Foo = {}));
148+
function c0(_a) {
149+
var _b = _a.z, x = _b.x, j = _b.y.j;
150+
}
151+
function c1(_a) {
152+
var z = (_a === void 0 ? { z: 10 } : _a).z;
153+
}
154+
function c2(_a) {
155+
var _b = _a.z, z = _b === void 0 ? 10 : _b;
156+
}
157+
function c3(_a) {
158+
var b = (_a === void 0 ? { b: "hello" } : _a).b;
159+
}
160+
function c5(_a) {
161+
var a = _a[0], b = _a[1], c = _a[2][0][0];
162+
}
163+
function c6(_a) {
164+
var a = _a[0], b = _a[1], _b = _a[2][0][0], c = _b === void 0 ? 1 : _b;
165+
}
166+
c0({ z: { x: 1, y: { j: "world" } } }); // Implied type is { z: {x: any, y: {j: any}} }
167+
c0({ z: { x: "string", y: { j: true } } }); // Implied type is { z: {x: any, y: {j: any}} }
168+
c1(); // Implied type is {z:number}?
169+
c1({ z: 1 }); // Implied type is {z:number}?
170+
c2({}); // Implied type is {z?: number}
171+
c2({ z: 1 }); // Implied type is {z?: number}
172+
c3({ b: 1 }); // Implied type is { b: number|string }.
173+
c5([1, 2, [["string"]]]); // Implied type is is [any, any, [[any]]]
174+
c5([1, 2, [["string"]], false, true]); // Implied type is is [any, any, [[any]]]
175+
// A parameter can be marked optional by following its name or binding pattern with a question mark (?)
176+
// or by including an initializer.
177+
function d0(x) { }
178+
function d0(x) {
179+
if (x === void 0) { x = 10; }
180+
}
181+
var C2 = (function () {
182+
function C2() {
183+
}
184+
C2.prototype.d3 = function () { };
185+
C2.prototype.d4 = function () { };
186+
C2.prototype.e0 = function (_a) {
187+
var a = _a[0], b = _a[1], c = _a[2];
188+
};
189+
return C2;
190+
})();
191+
var C3 = (function () {
192+
function C3() {
193+
}
194+
C3.prototype.d3 = function (_a) {
195+
var a = _a[0], b = _a[1], c = _a[2];
196+
};
197+
C3.prototype.d4 = function (_a) {
198+
var x = _a.x, y = _a.y, z = _a.z;
199+
};
200+
C3.prototype.e0 = function (_a) {
201+
var a = _a[0], b = _a[1], c = _a[2];
202+
};
203+
return C3;
204+
})();
205+
function d5(_a) {
206+
var _b = _a === void 0 ? { x: 1, y: 2 } : _a, x = _b.x, y = _b.y;
207+
}
208+
d5(); // Parameter is optional as its declaration included an initializer
209+
// Destructuring parameter declarations do not permit type annotations on the individual binding patterns,
210+
// as such annotations would conflict with the already established meaning of colons in object literals.
211+
// Type annotations must instead be written on the top- level parameter declaration
212+
function e1(_a) {
213+
var number = _a.x;
214+
} // x has type any NOT number
215+
function e2(_a) {
216+
var x = _a.x;
217+
} // x is type number
218+
function e3(_a) {
219+
var x = _a.x;
220+
} // x is an optional with type number
221+
function e4(_a) {
222+
var _b = _a.x, number = _b[0], string = _b[1], any = _b[2];
223+
} // x has type [any, any, any]
224+
function e5(_a) {
225+
var _b = _a.x, a = _b[0], b = _b[1], c = _b[2];
226+
} // x has type [any, any, any]

0 commit comments

Comments
 (0)