Skip to content

Commit 2263a1e

Browse files
authored
Merge pull request #20071 from Microsoft/error-on-excess-spread-arguments
Error on excess spread arguments
2 parents b6f9605 + 6a08820 commit 2263a1e

11 files changed

+44
-93
lines changed

src/compiler/checker.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16102,10 +16102,10 @@ namespace ts {
1610216102
return false;
1610316103
}
1610416104

16105-
// If spread arguments are present, check that they correspond to a rest parameter. If so, no
16106-
// further checking is necessary.
16105+
// If a spread argument is present, check that it corresponds to a rest parameter or at least that it's in the valid range.
1610716106
if (spreadArgIndex >= 0) {
16108-
return isRestParameterIndex(signature, spreadArgIndex) || spreadArgIndex >= signature.minArgumentCount;
16107+
return isRestParameterIndex(signature, spreadArgIndex) ||
16108+
signature.minArgumentCount <= spreadArgIndex && spreadArgIndex < signature.parameters.length;
1610916109
}
1611016110

1611116111
// Too many arguments implies incorrect arity.
@@ -16813,10 +16813,13 @@ namespace ts {
1681316813
const paramCount = hasRestParameter ? min :
1681416814
min < max ? min + "-" + max :
1681516815
min;
16816-
const argCount = args.length - (hasSpreadArgument ? 1 : 0);
16817-
const error = hasRestParameter && hasSpreadArgument ? Diagnostics.Expected_at_least_0_arguments_but_got_a_minimum_of_1 :
16816+
let argCount = args.length;
16817+
if (argCount <= max && hasSpreadArgument) {
16818+
argCount--;
16819+
}
16820+
const error = hasRestParameter && hasSpreadArgument ? Diagnostics.Expected_at_least_0_arguments_but_got_1_or_more :
1681816821
hasRestParameter ? Diagnostics.Expected_at_least_0_arguments_but_got_1 :
16819-
hasSpreadArgument ? Diagnostics.Expected_0_arguments_but_got_a_minimum_of_1 :
16822+
hasSpreadArgument ? Diagnostics.Expected_0_arguments_but_got_1_or_more :
1682016823
Diagnostics.Expected_0_arguments_but_got_1;
1682116824
diagnostics.add(createDiagnosticForNode(node, error, paramCount, argCount));
1682216825
}

src/compiler/diagnosticMessages.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1920,11 +1920,11 @@
19201920
"category": "Error",
19211921
"code": 2555
19221922
},
1923-
"Expected {0} arguments, but got a minimum of {1}.": {
1923+
"Expected {0} arguments, but got {1} or more.": {
19241924
"category": "Error",
19251925
"code": 2556
19261926
},
1927-
"Expected at least {0} arguments, but got a minimum of {1}.": {
1927+
"Expected at least {0} arguments, but got {1} or more.": {
19281928
"category": "Error",
19291929
"code": 2557
19301930
},

tests/baselines/reference/callWithSpread2.errors.txt

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
1-
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(30,5): error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'number'.
1+
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(22,1): error TS2556: Expected 1 arguments, but got 2 or more.
2+
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(23,1): error TS2556: Expected 0 arguments, but got 1 or more.
3+
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(26,5): error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'number'.
24
Type 'string' is not assignable to type 'number'.
3-
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(31,5): error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'number'.
5+
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(27,5): error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'number'.
46
Type 'string' is not assignable to type 'number'.
5-
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(32,13): error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'number'.
7+
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(28,13): error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'number'.
68
Type 'string' is not assignable to type 'number'.
7-
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(33,13): error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'number'.
9+
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(29,13): error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'number'.
810
Type 'string' is not assignable to type 'number'.
9-
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(34,11): error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'number'.
11+
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(30,11): error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'number'.
1012
Type 'string' is not assignable to type 'number'.
11-
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(35,11): error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'number'.
13+
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(31,11): error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'number'.
1214
Type 'string' is not assignable to type 'number'.
13-
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(36,1): error TS2556: Expected 1-3 arguments, but got a minimum of 0.
14-
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(37,1): error TS2556: Expected 1-3 arguments, but got a minimum of 0.
15-
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(38,1): error TS2556: Expected 1-3 arguments, but got a minimum of 0.
15+
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(32,1): error TS2556: Expected 1-3 arguments, but got 0 or more.
16+
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(33,1): error TS2556: Expected 1-3 arguments, but got 0 or more.
17+
tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(34,1): error TS2556: Expected 1-3 arguments, but got 0 or more.
1618

1719

18-
==== tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts (9 errors) ====
20+
==== tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts (11 errors) ====
1921
declare function all(a?: number, b?: number): void;
2022
declare function weird(a?: number | string, b?: number | string): void;
2123
declare function prefix(s: string, a?: number, b?: number): void;
@@ -36,13 +38,13 @@ tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(38,1): erro
3638
rest("d", ...ns)
3739

3840

39-
// this covers the arguments case
41+
// extra arguments
4042
normal("g", ...ns)
41-
normal("h", ...mixed)
42-
normal("i", ...tuple)
43+
~~~~~~~~~~~~~~~~~~
44+
!!! error TS2556: Expected 1 arguments, but got 2 or more.
4345
thunk(...ns)
44-
thunk(...mixed)
45-
thunk(...tuple)
46+
~~~~~~~~~~~~
47+
!!! error TS2556: Expected 0 arguments, but got 1 or more.
4648

4749
// bad
4850
all(...mixed)
@@ -71,11 +73,11 @@ tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts(38,1): erro
7173
!!! error TS2345: Type 'string' is not assignable to type 'number'.
7274
prefix(...ns) // required parameters are required
7375
~~~~~~~~~~~~~
74-
!!! error TS2556: Expected 1-3 arguments, but got a minimum of 0.
76+
!!! error TS2556: Expected 1-3 arguments, but got 0 or more.
7577
prefix(...mixed)
7678
~~~~~~~~~~~~~~~~
77-
!!! error TS2556: Expected 1-3 arguments, but got a minimum of 0.
79+
!!! error TS2556: Expected 1-3 arguments, but got 0 or more.
7880
prefix(...tuple)
7981
~~~~~~~~~~~~~~~~
80-
!!! error TS2556: Expected 1-3 arguments, but got a minimum of 0.
82+
!!! error TS2556: Expected 1-3 arguments, but got 0 or more.
8183

tests/baselines/reference/callWithSpread2.js

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,9 @@ prefix("a", ...ns)
1919
rest("d", ...ns)
2020

2121

22-
// this covers the arguments case
22+
// extra arguments
2323
normal("g", ...ns)
24-
normal("h", ...mixed)
25-
normal("i", ...tuple)
2624
thunk(...ns)
27-
thunk(...mixed)
28-
thunk(...tuple)
2925

3026
// bad
3127
all(...mixed)
@@ -47,13 +43,9 @@ weird.apply(void 0, mixed);
4743
weird.apply(void 0, tuple);
4844
prefix.apply(void 0, ["a"].concat(ns));
4945
rest.apply(void 0, ["d"].concat(ns));
50-
// this covers the arguments case
46+
// extra arguments
5147
normal.apply(void 0, ["g"].concat(ns));
52-
normal.apply(void 0, ["h"].concat(mixed));
53-
normal.apply(void 0, ["i"].concat(tuple));
5448
thunk.apply(void 0, ns);
55-
thunk.apply(void 0, mixed);
56-
thunk.apply(void 0, tuple);
5749
// bad
5850
all.apply(void 0, mixed);
5951
all.apply(void 0, tuple);

tests/baselines/reference/callWithSpread2.symbols

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -64,31 +64,15 @@ rest("d", ...ns)
6464
>ns : Symbol(ns, Decl(callWithSpread2.ts, 7, 11))
6565

6666

67-
// this covers the arguments case
67+
// extra arguments
6868
normal("g", ...ns)
6969
>normal : Symbol(normal, Decl(callWithSpread2.ts, 3, 83))
7070
>ns : Symbol(ns, Decl(callWithSpread2.ts, 7, 11))
7171

72-
normal("h", ...mixed)
73-
>normal : Symbol(normal, Decl(callWithSpread2.ts, 3, 83))
74-
>mixed : Symbol(mixed, Decl(callWithSpread2.ts, 8, 11))
75-
76-
normal("i", ...tuple)
77-
>normal : Symbol(normal, Decl(callWithSpread2.ts, 3, 83))
78-
>tuple : Symbol(tuple, Decl(callWithSpread2.ts, 9, 11))
79-
8072
thunk(...ns)
8173
>thunk : Symbol(thunk, Decl(callWithSpread2.ts, 4, 41))
8274
>ns : Symbol(ns, Decl(callWithSpread2.ts, 7, 11))
8375

84-
thunk(...mixed)
85-
>thunk : Symbol(thunk, Decl(callWithSpread2.ts, 4, 41))
86-
>mixed : Symbol(mixed, Decl(callWithSpread2.ts, 8, 11))
87-
88-
thunk(...tuple)
89-
>thunk : Symbol(thunk, Decl(callWithSpread2.ts, 4, 41))
90-
>tuple : Symbol(tuple, Decl(callWithSpread2.ts, 9, 11))
91-
9276
// bad
9377
all(...mixed)
9478
>all : Symbol(all, Decl(callWithSpread2.ts, 0, 0))

tests/baselines/reference/callWithSpread2.types

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -78,46 +78,20 @@ rest("d", ...ns)
7878
>ns : number[]
7979

8080

81-
// this covers the arguments case
81+
// extra arguments
8282
normal("g", ...ns)
8383
>normal("g", ...ns) : void
8484
>normal : (s: string) => void
8585
>"g" : "g"
8686
>...ns : number
8787
>ns : number[]
8888

89-
normal("h", ...mixed)
90-
>normal("h", ...mixed) : void
91-
>normal : (s: string) => void
92-
>"h" : "h"
93-
>...mixed : string | number
94-
>mixed : (string | number)[]
95-
96-
normal("i", ...tuple)
97-
>normal("i", ...tuple) : void
98-
>normal : (s: string) => void
99-
>"i" : "i"
100-
>...tuple : string | number
101-
>tuple : [number, string]
102-
10389
thunk(...ns)
10490
>thunk(...ns) : string
10591
>thunk : () => string
10692
>...ns : number
10793
>ns : number[]
10894

109-
thunk(...mixed)
110-
>thunk(...mixed) : string
111-
>thunk : () => string
112-
>...mixed : string | number
113-
>mixed : (string | number)[]
114-
115-
thunk(...tuple)
116-
>thunk(...tuple) : string
117-
>thunk : () => string
118-
>...tuple : string | number
119-
>tuple : [number, string]
120-
12195
// bad
12296
all(...mixed)
12397
>all(...mixed) : void

tests/baselines/reference/iteratorSpreadInCall.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
tests/cases/conformance/es6/spread/iteratorSpreadInCall.ts(15,1): error TS2556: Expected 1 arguments, but got a minimum of 0.
1+
tests/cases/conformance/es6/spread/iteratorSpreadInCall.ts(15,1): error TS2556: Expected 1 arguments, but got 0 or more.
22

33

44
==== tests/cases/conformance/es6/spread/iteratorSpreadInCall.ts (1 errors) ====
@@ -18,4 +18,4 @@ tests/cases/conformance/es6/spread/iteratorSpreadInCall.ts(15,1): error TS2556:
1818

1919
foo(...new SymbolIterator);
2020
~~~~~~~~~~~~~~~~~~~~~~~~~~
21-
!!! error TS2556: Expected 1 arguments, but got a minimum of 0.
21+
!!! error TS2556: Expected 1 arguments, but got 0 or more.

tests/baselines/reference/iteratorSpreadInCall10.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
tests/cases/conformance/es6/spread/iteratorSpreadInCall10.ts(15,1): error TS2556: Expected 1 arguments, but got a minimum of 0.
1+
tests/cases/conformance/es6/spread/iteratorSpreadInCall10.ts(15,1): error TS2556: Expected 1 arguments, but got 0 or more.
22

33

44
==== tests/cases/conformance/es6/spread/iteratorSpreadInCall10.ts (1 errors) ====
@@ -18,4 +18,4 @@ tests/cases/conformance/es6/spread/iteratorSpreadInCall10.ts(15,1): error TS2556
1818

1919
foo(...new SymbolIterator);
2020
~~~~~~~~~~~~~~~~~~~~~~~~~~
21-
!!! error TS2556: Expected 1 arguments, but got a minimum of 0.
21+
!!! error TS2556: Expected 1 arguments, but got 0 or more.

tests/baselines/reference/iteratorSpreadInCall2.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
tests/cases/conformance/es6/spread/iteratorSpreadInCall2.ts(15,1): error TS2556: Expected 1 arguments, but got a minimum of 0.
1+
tests/cases/conformance/es6/spread/iteratorSpreadInCall2.ts(15,1): error TS2556: Expected 1 arguments, but got 0 or more.
22

33

44
==== tests/cases/conformance/es6/spread/iteratorSpreadInCall2.ts (1 errors) ====
@@ -18,4 +18,4 @@ tests/cases/conformance/es6/spread/iteratorSpreadInCall2.ts(15,1): error TS2556:
1818

1919
foo(...new SymbolIterator);
2020
~~~~~~~~~~~~~~~~~~~~~~~~~~
21-
!!! error TS2556: Expected 1 arguments, but got a minimum of 0.
21+
!!! error TS2556: Expected 1 arguments, but got 0 or more.

tests/baselines/reference/iteratorSpreadInCall4.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
tests/cases/conformance/es6/spread/iteratorSpreadInCall4.ts(15,1): error TS2557: Expected at least 1 arguments, but got a minimum of 0.
1+
tests/cases/conformance/es6/spread/iteratorSpreadInCall4.ts(15,1): error TS2557: Expected at least 1 arguments, but got 0 or more.
22

33

44
==== tests/cases/conformance/es6/spread/iteratorSpreadInCall4.ts (1 errors) ====
@@ -18,4 +18,4 @@ tests/cases/conformance/es6/spread/iteratorSpreadInCall4.ts(15,1): error TS2557:
1818

1919
foo(...new SymbolIterator);
2020
~~~~~~~~~~~~~~~~~~~~~~~~~~
21-
!!! error TS2557: Expected at least 1 arguments, but got a minimum of 0.
21+
!!! error TS2557: Expected at least 1 arguments, but got 0 or more.

tests/cases/conformance/expressions/functionCalls/callWithSpread2.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,9 @@ prefix("a", ...ns)
1818
rest("d", ...ns)
1919

2020

21-
// this covers the arguments case
21+
// extra arguments
2222
normal("g", ...ns)
23-
normal("h", ...mixed)
24-
normal("i", ...tuple)
2523
thunk(...ns)
26-
thunk(...mixed)
27-
thunk(...tuple)
2824

2925
// bad
3026
all(...mixed)

0 commit comments

Comments
 (0)