Skip to content

Commit 7b55d18

Browse files
collin5weswigham
authored andcommitted
Giving too many arguments should error on the first argument that exceeds arity (#27982)
* span on first arg that exceeds arity * refactor baseline * handle cases for spread arguments * refactor + add coverage for tuple spread cases * create diagnostic on NodeArray of exceeding args * test function overloading
1 parent ab81536 commit 7b55d18

File tree

58 files changed

+514
-181
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+514
-181
lines changed

src/compiler/checker.ts

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20526,7 +20526,13 @@ namespace ts {
2052620526
argCount--;
2052720527
}
2052820528

20529+
let spanArray: NodeArray<Node>;
2052920530
let related: DiagnosticWithLocation | undefined;
20531+
20532+
const error = hasRestParameter || hasSpreadArgument ? hasRestParameter && hasSpreadArgument ? Diagnostics.Expected_at_least_0_arguments_but_got_1_or_more :
20533+
hasRestParameter ? Diagnostics.Expected_at_least_0_arguments_but_got_1 :
20534+
Diagnostics.Expected_0_arguments_but_got_1_or_more : Diagnostics.Expected_0_arguments_but_got_1;
20535+
2053020536
if (closestSignature && getMinArgumentCount(closestSignature) > argCount && closestSignature.declaration) {
2053120537
const paramDecl = closestSignature.declaration.parameters[closestSignature.thisParameter ? argCount + 1 : argCount];
2053220538
if (paramDecl) {
@@ -20537,17 +20543,33 @@ namespace ts {
2053720543
);
2053820544
}
2053920545
}
20540-
if (hasRestParameter || hasSpreadArgument) {
20541-
const error = hasRestParameter && hasSpreadArgument ? Diagnostics.Expected_at_least_0_arguments_but_got_1_or_more :
20542-
hasRestParameter ? Diagnostics.Expected_at_least_0_arguments_but_got_1 :
20543-
Diagnostics.Expected_0_arguments_but_got_1_or_more;
20546+
if (min < argCount && argCount < max) {
20547+
return createDiagnosticForNode(node, Diagnostics.No_overload_expects_0_arguments_but_overloads_do_exist_that_expect_either_1_or_2_arguments, argCount, belowArgCount, aboveArgCount);
20548+
}
20549+
20550+
if (!hasSpreadArgument && argCount < min) {
2054420551
const diagnostic = createDiagnosticForNode(node, error, paramRange, argCount);
2054520552
return related ? addRelatedInfo(diagnostic, related) : diagnostic;
2054620553
}
20547-
if (min < argCount && argCount < max) {
20548-
return createDiagnosticForNode(node, Diagnostics.No_overload_expects_0_arguments_but_overloads_do_exist_that_expect_either_1_or_2_arguments, argCount, belowArgCount, aboveArgCount);
20554+
20555+
if (hasRestParameter || hasSpreadArgument) {
20556+
spanArray = createNodeArray(args);
20557+
if (hasSpreadArgument && argCount) {
20558+
const nextArg = elementAt(args, getSpreadArgumentIndex(args) + 1) || undefined;
20559+
spanArray = createNodeArray(args.slice(max > argCount && nextArg ? args.indexOf(nextArg) : max));
20560+
}
20561+
}
20562+
else {
20563+
spanArray = createNodeArray(args.slice(max));
20564+
}
20565+
20566+
spanArray.pos = first(spanArray).pos;
20567+
spanArray.end = last(spanArray).end;
20568+
if (spanArray.end === spanArray.pos) {
20569+
spanArray.end++;
2054920570
}
20550-
const diagnostic = createDiagnosticForNode(node, Diagnostics.Expected_0_arguments_but_got_1, paramRange, argCount);
20571+
const diagnostic = createDiagnosticForNodeArray(
20572+
getSourceFileOfNode(node), spanArray, error, paramRange, argCount);
2055120573
return related ? addRelatedInfo(diagnostic, related) : diagnostic;
2055220574
}
2055320575

tests/baselines/reference/ES5SymbolProperty5.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
tests/cases/conformance/Symbols/ES5SymbolProperty5.ts(7,1): error TS2554: Expected 0 arguments, but got 1.
1+
tests/cases/conformance/Symbols/ES5SymbolProperty5.ts(7,26): error TS2554: Expected 0 arguments, but got 1.
22

33

44
==== tests/cases/conformance/Symbols/ES5SymbolProperty5.ts (1 errors) ====
@@ -9,5 +9,5 @@ tests/cases/conformance/Symbols/ES5SymbolProperty5.ts(7,1): error TS2554: Expect
99
}
1010

1111
(new C)[Symbol.iterator](0) // Should error
12-
~~~~~~~~~~~~~~~~~~~~~~~~~~~
12+
~
1313
!!! error TS2554: Expected 0 arguments, but got 1.

tests/baselines/reference/bigintWithoutLib.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ tests/cases/compiler/bigintWithoutLib.ts(7,30): error TS2737: BigInt literals ar
66
tests/cases/compiler/bigintWithoutLib.ts(8,13): error TS2304: Cannot find name 'BigInt'.
77
tests/cases/compiler/bigintWithoutLib.ts(8,31): error TS2737: BigInt literals are not available when targeting lower than ESNext.
88
tests/cases/compiler/bigintWithoutLib.ts(9,1): error TS2322: Type 'Object' is not assignable to type 'bigint'.
9-
tests/cases/compiler/bigintWithoutLib.ts(11,13): error TS2554: Expected 0 arguments, but got 1.
9+
tests/cases/compiler/bigintWithoutLib.ts(11,32): error TS2554: Expected 0 arguments, but got 1.
1010
tests/cases/compiler/bigintWithoutLib.ts(15,18): error TS2304: Cannot find name 'BigInt64Array'.
1111
tests/cases/compiler/bigintWithoutLib.ts(15,38): error TS2552: Cannot find name 'BigInt64Array'. Did you mean 'bigIntArray'?
1212
tests/cases/compiler/bigintWithoutLib.ts(16,19): error TS2552: Cannot find name 'BigInt64Array'. Did you mean 'bigIntArray'?
@@ -73,7 +73,7 @@ tests/cases/compiler/bigintWithoutLib.ts(49,22): error TS2339: Property 'getBigU
7373
!!! error TS2322: Type 'Object' is not assignable to type 'bigint'.
7474
let stringVal: string = bigintVal.toString(); // should not error - bigintVal inferred as {}
7575
stringVal = bigintVal.toString(2); // should error - bigintVal inferred as {}
76-
~~~~~~~~~~~~~~~~~~~~~
76+
~
7777
!!! error TS2554: Expected 0 arguments, but got 1.
7878
stringVal = bigintVal.toLocaleString(); // should not error - bigintVal inferred as {}
7979

tests/baselines/reference/blockScopedSameNameFunctionDeclarationES5.errors.txt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
tests/cases/compiler/blockScopedSameNameFunctionDeclarationES5.ts(3,18): error TS2393: Duplicate function implementation.
2-
tests/cases/compiler/blockScopedSameNameFunctionDeclarationES5.ts(5,9): error TS2554: Expected 0 arguments, but got 1.
2+
tests/cases/compiler/blockScopedSameNameFunctionDeclarationES5.ts(5,13): error TS2554: Expected 0 arguments, but got 1.
33
tests/cases/compiler/blockScopedSameNameFunctionDeclarationES5.ts(8,18): error TS2393: Duplicate function implementation.
4-
tests/cases/compiler/blockScopedSameNameFunctionDeclarationES5.ts(10,9): error TS2554: Expected 0 arguments, but got 1.
5-
tests/cases/compiler/blockScopedSameNameFunctionDeclarationES5.ts(12,5): error TS2554: Expected 0 arguments, but got 1.
4+
tests/cases/compiler/blockScopedSameNameFunctionDeclarationES5.ts(10,13): error TS2554: Expected 0 arguments, but got 1.
5+
tests/cases/compiler/blockScopedSameNameFunctionDeclarationES5.ts(12,9): error TS2554: Expected 0 arguments, but got 1.
66
tests/cases/compiler/blockScopedSameNameFunctionDeclarationES5.ts(16,1): error TS2554: Expected 1 arguments, but got 0.
77

88

@@ -14,7 +14,7 @@ tests/cases/compiler/blockScopedSameNameFunctionDeclarationES5.ts(16,1): error T
1414
!!! error TS2393: Duplicate function implementation.
1515
foo();
1616
foo(10); // not ok
17-
~~~~~~~
17+
~~
1818
!!! error TS2554: Expected 0 arguments, but got 1.
1919
}
2020
else {
@@ -23,11 +23,11 @@ tests/cases/compiler/blockScopedSameNameFunctionDeclarationES5.ts(16,1): error T
2323
!!! error TS2393: Duplicate function implementation.
2424
foo();
2525
foo(10); // not ok
26-
~~~~~~~
26+
~~
2727
!!! error TS2554: Expected 0 arguments, but got 1.
2828
}
2929
foo(10); // not ok
30-
~~~~~~~
30+
~~
3131
!!! error TS2554: Expected 0 arguments, but got 1.
3232
foo();
3333
}

tests/baselines/reference/blockScopedSameNameFunctionDeclarationES6.errors.txt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
tests/cases/compiler/blockScopedSameNameFunctionDeclarationES6.ts(3,18): error TS2393: Duplicate function implementation.
2-
tests/cases/compiler/blockScopedSameNameFunctionDeclarationES6.ts(5,9): error TS2554: Expected 0 arguments, but got 1.
2+
tests/cases/compiler/blockScopedSameNameFunctionDeclarationES6.ts(5,13): error TS2554: Expected 0 arguments, but got 1.
33
tests/cases/compiler/blockScopedSameNameFunctionDeclarationES6.ts(8,18): error TS2393: Duplicate function implementation.
4-
tests/cases/compiler/blockScopedSameNameFunctionDeclarationES6.ts(10,9): error TS2554: Expected 0 arguments, but got 1.
5-
tests/cases/compiler/blockScopedSameNameFunctionDeclarationES6.ts(12,5): error TS2554: Expected 0 arguments, but got 1.
4+
tests/cases/compiler/blockScopedSameNameFunctionDeclarationES6.ts(10,13): error TS2554: Expected 0 arguments, but got 1.
5+
tests/cases/compiler/blockScopedSameNameFunctionDeclarationES6.ts(12,9): error TS2554: Expected 0 arguments, but got 1.
66
tests/cases/compiler/blockScopedSameNameFunctionDeclarationES6.ts(16,1): error TS2554: Expected 1 arguments, but got 0.
77

88

@@ -14,7 +14,7 @@ tests/cases/compiler/blockScopedSameNameFunctionDeclarationES6.ts(16,1): error T
1414
!!! error TS2393: Duplicate function implementation.
1515
foo();
1616
foo(10); // not ok
17-
~~~~~~~
17+
~~
1818
!!! error TS2554: Expected 0 arguments, but got 1.
1919
}
2020
else {
@@ -23,11 +23,11 @@ tests/cases/compiler/blockScopedSameNameFunctionDeclarationES6.ts(16,1): error T
2323
!!! error TS2393: Duplicate function implementation.
2424
foo();
2525
foo(10);// not ok
26-
~~~~~~~
26+
~~
2727
!!! error TS2554: Expected 0 arguments, but got 1.
2828
}
2929
foo(10); // not ok
30-
~~~~~~~
30+
~~
3131
!!! error TS2554: Expected 0 arguments, but got 1.
3232
foo();
3333
}

tests/baselines/reference/blockScopedSameNameFunctionDeclarationStrictES5.errors.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
tests/cases/compiler/blockScopedSameNameFunctionDeclarationStrictES5.ts(4,18): error TS1250: Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'.
2-
tests/cases/compiler/blockScopedSameNameFunctionDeclarationStrictES5.ts(6,9): error TS2554: Expected 0 arguments, but got 1.
2+
tests/cases/compiler/blockScopedSameNameFunctionDeclarationStrictES5.ts(6,13): error TS2554: Expected 0 arguments, but got 1.
33
tests/cases/compiler/blockScopedSameNameFunctionDeclarationStrictES5.ts(9,18): error TS1250: Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'.
4-
tests/cases/compiler/blockScopedSameNameFunctionDeclarationStrictES5.ts(11,9): error TS2554: Expected 0 arguments, but got 1.
4+
tests/cases/compiler/blockScopedSameNameFunctionDeclarationStrictES5.ts(11,13): error TS2554: Expected 0 arguments, but got 1.
55
tests/cases/compiler/blockScopedSameNameFunctionDeclarationStrictES5.ts(14,5): error TS2554: Expected 1 arguments, but got 0.
66
tests/cases/compiler/blockScopedSameNameFunctionDeclarationStrictES5.ts(17,1): error TS2554: Expected 1 arguments, but got 0.
77

@@ -15,7 +15,7 @@ tests/cases/compiler/blockScopedSameNameFunctionDeclarationStrictES5.ts(17,1): e
1515
!!! error TS1250: Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'.
1616
foo();
1717
foo(10); // not ok
18-
~~~~~~~
18+
~~
1919
!!! error TS2554: Expected 0 arguments, but got 1.
2020
}
2121
else {
@@ -24,7 +24,7 @@ tests/cases/compiler/blockScopedSameNameFunctionDeclarationStrictES5.ts(17,1): e
2424
!!! error TS1250: Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'.
2525
foo();
2626
foo(10); // not ok
27-
~~~~~~~
27+
~~
2828
!!! error TS2554: Expected 0 arguments, but got 1.
2929
}
3030
foo(10);

tests/baselines/reference/blockScopedSameNameFunctionDeclarationStrictES6.errors.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
tests/cases/compiler/blockScopedSameNameFunctionDeclarationStrictES6.ts(6,9): error TS2554: Expected 0 arguments, but got 1.
2-
tests/cases/compiler/blockScopedSameNameFunctionDeclarationStrictES6.ts(11,9): error TS2554: Expected 0 arguments, but got 1.
1+
tests/cases/compiler/blockScopedSameNameFunctionDeclarationStrictES6.ts(6,13): error TS2554: Expected 0 arguments, but got 1.
2+
tests/cases/compiler/blockScopedSameNameFunctionDeclarationStrictES6.ts(11,13): error TS2554: Expected 0 arguments, but got 1.
33
tests/cases/compiler/blockScopedSameNameFunctionDeclarationStrictES6.ts(14,5): error TS2554: Expected 1 arguments, but got 0.
44
tests/cases/compiler/blockScopedSameNameFunctionDeclarationStrictES6.ts(17,1): error TS2554: Expected 1 arguments, but got 0.
55

@@ -11,14 +11,14 @@ tests/cases/compiler/blockScopedSameNameFunctionDeclarationStrictES6.ts(17,1): e
1111
function foo() { }
1212
foo();
1313
foo(10); // not ok
14-
~~~~~~~
14+
~~
1515
!!! error TS2554: Expected 0 arguments, but got 1.
1616
}
1717
else {
1818
function foo() { }
1919
foo();
2020
foo(10); // not ok
21-
~~~~~~~
21+
~~
2222
!!! error TS2554: Expected 0 arguments, but got 1.
2323
}
2424
foo(10);

tests/baselines/reference/callOnInstance.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
tests/cases/compiler/callOnInstance.ts(1,18): error TS2300: Duplicate identifier 'D'.
22
tests/cases/compiler/callOnInstance.ts(3,15): error TS2300: Duplicate identifier 'D'.
3-
tests/cases/compiler/callOnInstance.ts(7,19): error TS2554: Expected 0 arguments, but got 1.
3+
tests/cases/compiler/callOnInstance.ts(7,25): error TS2554: Expected 0 arguments, but got 1.
44
tests/cases/compiler/callOnInstance.ts(10,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'C' has no compatible call signatures.
55

66

@@ -16,7 +16,7 @@ tests/cases/compiler/callOnInstance.ts(10,1): error TS2349: Cannot invoke an exp
1616
var s1: string = D(); // OK
1717

1818
var s2: string = (new D(1))();
19-
~~~~~~~~
19+
~
2020
!!! error TS2554: Expected 0 arguments, but got 1.
2121

2222
declare class C { constructor(value: number); }
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
tests/cases/conformance/expressions/functionCalls/callOverload.ts(7,7): error TS2554: Expected 1 arguments, but got 4.
2+
tests/cases/conformance/expressions/functionCalls/callOverload.ts(8,15): error TS2554: Expected 2 arguments, but got 4.
3+
tests/cases/conformance/expressions/functionCalls/callOverload.ts(10,1): error TS2555: Expected at least 1 arguments, but got 0.
4+
tests/cases/conformance/expressions/functionCalls/callOverload.ts(11,10): error TS2557: Expected at least 1 arguments, but got 0 or more.
5+
6+
7+
==== tests/cases/conformance/expressions/functionCalls/callOverload.ts (4 errors) ====
8+
declare function fn(x: any): void;
9+
declare function takeTwo(x: any, y: any): void;
10+
declare function withRest(a: any, ...args: Array<any>): void;
11+
var n: number[];
12+
13+
fn(1) // no error
14+
fn(1, 2, 3, 4)
15+
~~~~~~~
16+
!!! error TS2554: Expected 1 arguments, but got 4.
17+
takeTwo(1, 2, 3, 4)
18+
~~~~
19+
!!! error TS2554: Expected 2 arguments, but got 4.
20+
withRest('a', ...n); // no error
21+
withRest();
22+
~~~~~~~~~~
23+
!!! error TS2555: Expected at least 1 arguments, but got 0.
24+
!!! related TS6210 tests/cases/conformance/expressions/functionCalls/callOverload.ts:3:27: An argument for 'a' was not provided.
25+
withRest(...n);
26+
~~~~
27+
!!! error TS2557: Expected at least 1 arguments, but got 0 or more.
28+
!!! related TS6210 tests/cases/conformance/expressions/functionCalls/callOverload.ts:3:27: An argument for 'a' was not provided.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//// [callOverload.ts]
2+
declare function fn(x: any): void;
3+
declare function takeTwo(x: any, y: any): void;
4+
declare function withRest(a: any, ...args: Array<any>): void;
5+
var n: number[];
6+
7+
fn(1) // no error
8+
fn(1, 2, 3, 4)
9+
takeTwo(1, 2, 3, 4)
10+
withRest('a', ...n); // no error
11+
withRest();
12+
withRest(...n);
13+
14+
//// [callOverload.js]
15+
var n;
16+
fn(1); // no error
17+
fn(1, 2, 3, 4);
18+
takeTwo(1, 2, 3, 4);
19+
withRest.apply(void 0, ['a'].concat(n)); // no error
20+
withRest();
21+
withRest.apply(void 0, n);

0 commit comments

Comments
 (0)