Skip to content

extract rest params #17898

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 87 additions & 31 deletions src/compiler/checker.ts

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -1920,6 +1920,10 @@
"category": "Error",
"code": 2562
},
"A rest parameter in a function with optional parameters must be of an array type.": {
"category": "Error",
"code": 2563
},
"JSX element attributes type '{0}' may not be a union type.": {
"category": "Error",
"code": 2600
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration10_es6.ts(1,16): error TS2371: A parameter initializer is only allowed in a function or constructor implementation.
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration10_es6.ts(1,20): error TS2523: 'yield' expressions cannot be used in a parameter initializer.
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration10_es6.ts(1,26): error TS1005: ',' expected.
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration10_es6.ts(1,29): error TS1138: Parameter declaration expected.
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration10_es6.ts(1,29): error TS2304: Cannot find name 'yield'.
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration10_es6.ts(1,34): error TS1005: ';' expected.


==== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration10_es6.ts (5 errors) ====
==== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration10_es6.ts (6 errors) ====
function * foo(a = yield => yield) {
~~~~~~~~~
!!! error TS2371: A parameter initializer is only allowed in a function or constructor implementation.
~~~~~
!!! error TS2523: 'yield' expressions cannot be used in a parameter initializer.
~~
!!! error TS1005: ',' expected.
~~~~~
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts(1,20): error TS2371: A parameter initializer is only allowed in a function or constructor implementation.
tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts(1,24): error TS2524: 'await' expressions cannot be used in a parameter initializer.
tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts(1,30): error TS1109: Expression expected.
tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts(1,33): error TS1138: Parameter declaration expected.
tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts(1,33): error TS2304: Cannot find name 'await'.
Expand All @@ -8,10 +9,12 @@ tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclarati
tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts(1,53): error TS1109: Expression expected.


==== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts (8 errors) ====
==== tests/cases/conformance/async/es2017/functionDeclarations/asyncFunctionDeclaration10_es2017.ts (9 errors) ====
async function foo(a = await => await): Promise<void> {
~~~~~~~~~
!!! error TS2371: A parameter initializer is only allowed in a function or constructor implementation.
~~~~~
!!! error TS2524: 'await' expressions cannot be used in a parameter initializer.
~~
!!! error TS1109: Expression expected.
~~~~~
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration10_es5.ts(1,20): error TS2371: A parameter initializer is only allowed in a function or constructor implementation.
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration10_es5.ts(1,24): error TS2524: 'await' expressions cannot be used in a parameter initializer.
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration10_es5.ts(1,30): error TS1109: Expression expected.
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration10_es5.ts(1,33): error TS1138: Parameter declaration expected.
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration10_es5.ts(1,33): error TS2304: Cannot find name 'await'.
Expand All @@ -8,10 +9,12 @@ tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration1
tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration10_es5.ts(1,53): error TS1109: Expression expected.


==== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration10_es5.ts (8 errors) ====
==== tests/cases/conformance/async/es5/functionDeclarations/asyncFunctionDeclaration10_es5.ts (9 errors) ====
async function foo(a = await => await): Promise<void> {
~~~~~~~~~
!!! error TS2371: A parameter initializer is only allowed in a function or constructor implementation.
~~~~~
!!! error TS2524: 'await' expressions cannot be used in a parameter initializer.
~~
!!! error TS1109: Expression expected.
~~~~~
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration10_es6.ts(1,20): error TS2371: A parameter initializer is only allowed in a function or constructor implementation.
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration10_es6.ts(1,24): error TS2524: 'await' expressions cannot be used in a parameter initializer.
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration10_es6.ts(1,30): error TS1109: Expression expected.
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration10_es6.ts(1,33): error TS1138: Parameter declaration expected.
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration10_es6.ts(1,33): error TS2304: Cannot find name 'await'.
Expand All @@ -8,10 +9,12 @@ tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration1
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration10_es6.ts(1,53): error TS1109: Expression expected.


==== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration10_es6.ts (8 errors) ====
==== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration10_es6.ts (9 errors) ====
async function foo(a = await => await): Promise<void> {
~~~~~~~~~
!!! error TS2371: A parameter initializer is only allowed in a function or constructor implementation.
~~~~~
!!! error TS2524: 'await' expressions cannot be used in a parameter initializer.
~~
!!! error TS1109: Expression expected.
~~~~~
Expand Down
19 changes: 19 additions & 0 deletions tests/baselines/reference/destructureGenerics.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//// [destructureGenerics.ts]
declare function f<T extends any[]>(...args: T): T;
var x = f(1,2);
var x: [1, 2];
declare function g<T extends [number, number]>(...args: T): T;
var z = g(1,2);
var z: [1,2];
declare function h<T>(...args: T[]): T;
var b = h(1,2,3);
var b: number;


//// [destructureGenerics.js]
var x = f(1, 2);
var x;
var z = g(1, 2);
var z;
var b = h(1, 2, 3);
var b;
43 changes: 43 additions & 0 deletions tests/baselines/reference/destructureGenerics.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
=== tests/cases/compiler/destructureGenerics.ts ===
declare function f<T extends any[]>(...args: T): T;
>f : Symbol(f, Decl(destructureGenerics.ts, 0, 0))
>T : Symbol(T, Decl(destructureGenerics.ts, 0, 19))
>args : Symbol(args, Decl(destructureGenerics.ts, 0, 36))
>T : Symbol(T, Decl(destructureGenerics.ts, 0, 19))
>T : Symbol(T, Decl(destructureGenerics.ts, 0, 19))

var x = f(1,2);
>x : Symbol(x, Decl(destructureGenerics.ts, 1, 3), Decl(destructureGenerics.ts, 2, 3))
>f : Symbol(f, Decl(destructureGenerics.ts, 0, 0))

var x: [1, 2];
>x : Symbol(x, Decl(destructureGenerics.ts, 1, 3), Decl(destructureGenerics.ts, 2, 3))

declare function g<T extends [number, number]>(...args: T): T;
>g : Symbol(g, Decl(destructureGenerics.ts, 2, 14))
>T : Symbol(T, Decl(destructureGenerics.ts, 3, 19))
>args : Symbol(args, Decl(destructureGenerics.ts, 3, 47))
>T : Symbol(T, Decl(destructureGenerics.ts, 3, 19))
>T : Symbol(T, Decl(destructureGenerics.ts, 3, 19))

var z = g(1,2);
>z : Symbol(z, Decl(destructureGenerics.ts, 4, 3), Decl(destructureGenerics.ts, 5, 3))
>g : Symbol(g, Decl(destructureGenerics.ts, 2, 14))

var z: [1,2];
>z : Symbol(z, Decl(destructureGenerics.ts, 4, 3), Decl(destructureGenerics.ts, 5, 3))

declare function h<T>(...args: T[]): T;
>h : Symbol(h, Decl(destructureGenerics.ts, 5, 13))
>T : Symbol(T, Decl(destructureGenerics.ts, 6, 19))
>args : Symbol(args, Decl(destructureGenerics.ts, 6, 22))
>T : Symbol(T, Decl(destructureGenerics.ts, 6, 19))
>T : Symbol(T, Decl(destructureGenerics.ts, 6, 19))

var b = h(1,2,3);
>b : Symbol(b, Decl(destructureGenerics.ts, 7, 3), Decl(destructureGenerics.ts, 8, 3))
>h : Symbol(h, Decl(destructureGenerics.ts, 5, 13))

var b: number;
>b : Symbol(b, Decl(destructureGenerics.ts, 7, 3), Decl(destructureGenerics.ts, 8, 3))

53 changes: 53 additions & 0 deletions tests/baselines/reference/destructureGenerics.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
=== tests/cases/compiler/destructureGenerics.ts ===
declare function f<T extends any[]>(...args: T): T;
>f : <T extends any[]>(...args: T) => T
>T : T
>args : T
>T : T
>T : T

var x = f(1,2);
>x : [1, 2]
>f(1,2) : [1, 2]
>f : <T extends any[]>(...args: T) => T
>1 : 1
>2 : 2

var x: [1, 2];
>x : [1, 2]

declare function g<T extends [number, number]>(...args: T): T;
>g : <T extends [number, number]>(...args: T) => T
>T : T
>args : T
>T : T
>T : T

var z = g(1,2);
>z : [1, 2]
>g(1,2) : [1, 2]
>g : <T extends [number, number]>(...args: T) => T
>1 : 1
>2 : 2

var z: [1,2];
>z : [1, 2]

declare function h<T>(...args: T[]): T;
>h : <T>(...args: T[]) => T
>T : T
>args : T[]
>T : T
>T : T

var b = h(1,2,3);
>b : number
>h(1,2,3) : 1 | 2 | 3
>h : <T>(...args: T[]) => T
>1 : 1
>2 : 2
>3 : 3

var b: number;
>b : number

26 changes: 26 additions & 0 deletions tests/baselines/reference/destructureGenericsErrors.errors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
tests/cases/compiler/destructureGenericsErrors.ts(2,9): error TS2554: Expected 2 arguments, but got 1.
tests/cases/compiler/destructureGenericsErrors.ts(3,9): error TS2554: Expected 2 arguments, but got 3.
tests/cases/compiler/destructureGenericsErrors.ts(4,48): error TS2563: A rest parameter in a function with optional parameters must be of an array type.
tests/cases/compiler/destructureGenericsErrors.ts(4,55): error TS1047: A rest parameter cannot be optional.
tests/cases/compiler/destructureGenericsErrors.ts(6,60): error TS2563: A rest parameter in a function with optional parameters must be of an array type.


==== tests/cases/compiler/destructureGenericsErrors.ts (5 errors) ====
declare function g<T extends [number, number]>(...args: T): T;
var y = g(1); // error
~~~~
!!! error TS2554: Expected 2 arguments, but got 1.
var a = g(1,2,3); // error
~~~~~~~~
!!! error TS2554: Expected 2 arguments, but got 3.
declare function k<T extends [number, number]>(...args?: T): T;
~~~~~~~~~~~
!!! error TS2563: A rest parameter in a function with optional parameters must be of an array type.
~
!!! error TS1047: A rest parameter cannot be optional.
var u = k(1,2); // error
declare function m<T extends [number, number]>(a?: string, ...args: T): T;
~~~~~~~~~~
!!! error TS2563: A rest parameter in a function with optional parameters must be of an array type.
var v = m('a',1,2); // error

15 changes: 15 additions & 0 deletions tests/baselines/reference/destructureGenericsErrors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//// [destructureGenericsErrors.ts]
declare function g<T extends [number, number]>(...args: T): T;
var y = g(1); // error
var a = g(1,2,3); // error
declare function k<T extends [number, number]>(...args?: T): T;
var u = k(1,2); // error
declare function m<T extends [number, number]>(a?: string, ...args: T): T;
var v = m('a',1,2); // error


//// [destructureGenericsErrors.js]
var y = g(1); // error
var a = g(1, 2, 3); // error
var u = k(1, 2); // error
var v = m('a', 1, 2); // error
17 changes: 17 additions & 0 deletions tests/baselines/reference/destructureGenericsErrors.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
=== tests/cases/compiler/destructureGenericsErrors.ts ===
declare function g<T extends [number, number]>(...args: T): T;
>g : Symbol(g, Decl(destructureGenericsErrors.ts, 0, 0))
>T : Symbol(T, Decl(destructureGenericsErrors.ts, 0, 19))
>args : Symbol(args, Decl(destructureGenericsErrors.ts, 0, 47))
>T : Symbol(T, Decl(destructureGenericsErrors.ts, 0, 19))
>T : Symbol(T, Decl(destructureGenericsErrors.ts, 0, 19))

// var y = g(1); // error
// var y: [1];
var a = g(1,2,3); // error
>a : Symbol(a, Decl(destructureGenericsErrors.ts, 3, 3), Decl(destructureGenericsErrors.ts, 4, 3))
>g : Symbol(g, Decl(destructureGenericsErrors.ts, 0, 0))

var a: [1,2,3];
>a : Symbol(a, Decl(destructureGenericsErrors.ts, 3, 3), Decl(destructureGenericsErrors.ts, 4, 3))

21 changes: 21 additions & 0 deletions tests/baselines/reference/destructureGenericsErrors.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
=== tests/cases/compiler/destructureGenericsErrors.ts ===
declare function g<T extends [number, number]>(...args: T): T;
>g : <T extends [number, number]>(...args: T) => T
>T : T
>args : T
>T : T
>T : T

// var y = g(1); // error
// var y: [1];
var a = g(1,2,3); // error
>a : [1, 2, 3]
>g(1,2,3) : [1, 2, 3]
>g : <T extends [number, number]>(...args: T) => T
>1 : 1
>2 : 2
>3 : 3

var a: [1,2,3];
>a : [1, 2, 3]

Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(11,13): error TS2370: A rest parameter must be of an array type.
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(13,13): error TS2370: A rest parameter must be of an array type.
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(14,17): error TS1047: A rest parameter cannot be optional.
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(15,16): error TS1048: A rest parameter cannot have an initializer.
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(20,19): error TS2345: Argument of type 'true' is not assignable to parameter of type 'string | number'.
Expand All @@ -17,7 +15,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(
tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(34,28): error TS2304: Cannot find name 'E'.


==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts (12 errors) ====
==== tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts (10 errors) ====
// If the parameter is a rest parameter, the parameter type is any[]
// A type annotation for a rest parameter must denote an array type.

Expand All @@ -29,12 +27,8 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(
type stringOrNumArray = Array<String|Number>;

function a0(...x: [number, number, string]) { } // Error, rest parameter must be array type
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2370: A rest parameter must be of an array type.
function a1(...x: (number|string)[]) { }
function a2(...a: someArray) { } // Error, rest parameter must be array type
~~~~~~~~~~~~~~~
!!! error TS2370: A rest parameter must be of an array type.
function a3(...b?) { } // Error, can't be optional
~
!!! error TS1047: A rest parameter cannot be optional.
Expand Down
7 changes: 5 additions & 2 deletions tests/baselines/reference/iterableArrayPattern25.errors.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
tests/cases/conformance/es6/destructuring/iterableArrayPattern25.ts(1,33): error TS2501: A rest element cannot contain a binding pattern.
tests/cases/conformance/es6/destructuring/iterableArrayPattern25.ts(2,1): error TS2554: Expected 2 arguments, but got 1.


==== tests/cases/conformance/es6/destructuring/iterableArrayPattern25.ts (1 errors) ====
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern25.ts (2 errors) ====
function takeFirstTwoEntries(...[[k1, v1], [k2, v2]]) { }
~~~~~~~~~~~~~~~~~~~~
!!! error TS2501: A rest element cannot contain a binding pattern.
takeFirstTwoEntries(new Map([["", 0], ["hello", 1]]));
takeFirstTwoEntries(new Map([["", 0], ["hello", 1]]));
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2554: Expected 2 arguments, but got 1.
Loading