Issue 19220 function parameter arity (#24031)
* Added reference test case and diagnostics message * Adjusted arity checks to account for non-contiguous overloads * Code cleanup, baseline not yet commited * Accepted test baselines and minor implementation changes * Cleaned up baseline tracking the now renamed arity check test * Add range response when range contains only 2 values * Added recent baseline * Refined arity error messages when available overloads can be grouped * Rolled back code formatting * WIP cleanup needed in a few edge cases * Finished adding new more descriptive error messages * Code cleanup * Added simplified version of bugfix for #19220 * Rebased onto master * Removed whitespace after type assertion * Code review simplifications * Use correct diagnostic name * Code review changes and simplification of diagnostic message * Revert formatting changes
This commit is contained in:
parent
5f4a03c408
commit
66e9aaac18
7 changed files with 249 additions and 10 deletions
|
@ -19052,24 +19052,40 @@ namespace ts {
|
||||||
else if (args) {
|
else if (args) {
|
||||||
let min = Number.POSITIVE_INFINITY;
|
let min = Number.POSITIVE_INFINITY;
|
||||||
let max = Number.NEGATIVE_INFINITY;
|
let max = Number.NEGATIVE_INFINITY;
|
||||||
|
let belowArgCount = Number.NEGATIVE_INFINITY;
|
||||||
|
let aboveArgCount = Number.POSITIVE_INFINITY;
|
||||||
|
|
||||||
|
let argCount = args.length;
|
||||||
for (const sig of signatures) {
|
for (const sig of signatures) {
|
||||||
min = Math.min(min, getMinArgumentCount(sig));
|
const minCount = getMinArgumentCount(sig);
|
||||||
max = Math.max(max, getParameterCount(sig));
|
const maxCount = getParameterCount(sig);
|
||||||
|
if (minCount < argCount && minCount > belowArgCount) belowArgCount = minCount;
|
||||||
|
if (argCount < maxCount && maxCount < aboveArgCount) aboveArgCount = maxCount;
|
||||||
|
min = Math.min(min, minCount);
|
||||||
|
max = Math.max(max, maxCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
const hasRestParameter = some(signatures, hasEffectiveRestParameter);
|
const hasRestParameter = some(signatures, hasEffectiveRestParameter);
|
||||||
const hasSpreadArgument = getSpreadArgumentIndex(args) > -1;
|
const paramRange = hasRestParameter ? min :
|
||||||
const paramCount = hasRestParameter ? min :
|
|
||||||
min < max ? min + "-" + max :
|
min < max ? min + "-" + max :
|
||||||
min;
|
min;
|
||||||
let argCount = args.length;
|
const hasSpreadArgument = getSpreadArgumentIndex(args) > -1;
|
||||||
if (argCount <= max && hasSpreadArgument) {
|
if (argCount <= max && hasSpreadArgument) {
|
||||||
argCount--;
|
argCount--;
|
||||||
}
|
}
|
||||||
const error = hasRestParameter && hasSpreadArgument ? Diagnostics.Expected_at_least_0_arguments_but_got_1_or_more :
|
|
||||||
hasRestParameter ? Diagnostics.Expected_at_least_0_arguments_but_got_1 :
|
if (hasRestParameter || hasSpreadArgument) {
|
||||||
hasSpreadArgument ? Diagnostics.Expected_0_arguments_but_got_1_or_more :
|
const error = hasRestParameter && hasSpreadArgument ? Diagnostics.Expected_at_least_0_arguments_but_got_1_or_more :
|
||||||
Diagnostics.Expected_0_arguments_but_got_1;
|
hasRestParameter ? Diagnostics.Expected_at_least_0_arguments_but_got_1 :
|
||||||
diagnostics.add(createDiagnosticForNode(node, error, paramCount, argCount));
|
Diagnostics.Expected_0_arguments_but_got_1_or_more;
|
||||||
|
diagnostics.add(createDiagnosticForNode(node, error, paramRange, argCount));
|
||||||
|
}
|
||||||
|
else if (min < argCount && argCount < max) {
|
||||||
|
diagnostics.add(createDiagnosticForNode(node, Diagnostics.No_overload_expects_0_arguments_but_overloads_do_exist_that_expect_either_1_or_2_arguments, argCount, belowArgCount, aboveArgCount));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
diagnostics.add(createDiagnosticForNode(node, Diagnostics.Expected_0_arguments_but_got_1, paramRange, argCount));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (fallbackError) {
|
else if (fallbackError) {
|
||||||
diagnostics.add(createDiagnosticForNode(node, fallbackError));
|
diagnostics.add(createDiagnosticForNode(node, fallbackError));
|
||||||
|
|
|
@ -2056,6 +2056,10 @@
|
||||||
"category": "Error",
|
"category": "Error",
|
||||||
"code": 2574
|
"code": 2574
|
||||||
},
|
},
|
||||||
|
"No overload expects {0} arguments, but overloads do exist that expect either {1} or {2} arguments.": {
|
||||||
|
"category": "Error",
|
||||||
|
"code": 2575
|
||||||
|
},
|
||||||
"JSX element attributes type '{0}' may not be a union type.": {
|
"JSX element attributes type '{0}' may not be a union type.": {
|
||||||
"category": "Error",
|
"category": "Error",
|
||||||
"code": 2600
|
"code": 2600
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
tests/cases/compiler/functionParameterArityMismatch.ts(3,1): error TS2554: Expected 1-3 arguments, but got 0.
|
||||||
|
tests/cases/compiler/functionParameterArityMismatch.ts(4,1): error TS2575: No overload expects 2 arguments, but overloads do exist that expect either 1 or 3 arguments.
|
||||||
|
tests/cases/compiler/functionParameterArityMismatch.ts(5,1): error TS2554: Expected 1-3 arguments, but got 4.
|
||||||
|
tests/cases/compiler/functionParameterArityMismatch.ts(11,1): error TS2575: No overload expects 1 arguments, but overloads do exist that expect either 0 or 2 arguments.
|
||||||
|
tests/cases/compiler/functionParameterArityMismatch.ts(12,1): error TS2575: No overload expects 3 arguments, but overloads do exist that expect either 2 or 4 arguments.
|
||||||
|
tests/cases/compiler/functionParameterArityMismatch.ts(13,1): error TS2575: No overload expects 5 arguments, but overloads do exist that expect either 4 or 6 arguments.
|
||||||
|
tests/cases/compiler/functionParameterArityMismatch.ts(14,1): error TS2554: Expected 0-6 arguments, but got 7.
|
||||||
|
|
||||||
|
|
||||||
|
==== tests/cases/compiler/functionParameterArityMismatch.ts (7 errors) ====
|
||||||
|
declare function f1(a: number);
|
||||||
|
declare function f1(a: number, b: number, c: number);
|
||||||
|
f1();
|
||||||
|
~~~~
|
||||||
|
!!! error TS2554: Expected 1-3 arguments, but got 0.
|
||||||
|
f1(1, 2);
|
||||||
|
~~~~~~~~
|
||||||
|
!!! error TS2575: No overload expects 2 arguments, but overloads do exist that expect either 1 or 3 arguments.
|
||||||
|
f1(1, 2, 3, 4);
|
||||||
|
~~~~~~~~~~~~~~
|
||||||
|
!!! error TS2554: Expected 1-3 arguments, but got 4.
|
||||||
|
|
||||||
|
declare function f2();
|
||||||
|
declare function f2(a: number, b: number);
|
||||||
|
declare function f2(a: number, b: number, c: number, d: number);
|
||||||
|
declare function f2(a: number, b: number, c: number, d: number, e: number, f: number);
|
||||||
|
f2(1);
|
||||||
|
~~~~~
|
||||||
|
!!! error TS2575: No overload expects 1 arguments, but overloads do exist that expect either 0 or 2 arguments.
|
||||||
|
f2(1, 2, 3);
|
||||||
|
~~~~~~~~~~~
|
||||||
|
!!! error TS2575: No overload expects 3 arguments, but overloads do exist that expect either 2 or 4 arguments.
|
||||||
|
f2(1, 2, 3, 4, 5);
|
||||||
|
~~~~~~~~~~~~~~~~~
|
||||||
|
!!! error TS2575: No overload expects 5 arguments, but overloads do exist that expect either 4 or 6 arguments.
|
||||||
|
f2(1, 2, 3, 4, 5, 6, 7);
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
!!! error TS2554: Expected 0-6 arguments, but got 7.
|
||||||
|
|
25
tests/baselines/reference/functionParameterArityMismatch.js
Normal file
25
tests/baselines/reference/functionParameterArityMismatch.js
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
//// [functionParameterArityMismatch.ts]
|
||||||
|
declare function f1(a: number);
|
||||||
|
declare function f1(a: number, b: number, c: number);
|
||||||
|
f1();
|
||||||
|
f1(1, 2);
|
||||||
|
f1(1, 2, 3, 4);
|
||||||
|
|
||||||
|
declare function f2();
|
||||||
|
declare function f2(a: number, b: number);
|
||||||
|
declare function f2(a: number, b: number, c: number, d: number);
|
||||||
|
declare function f2(a: number, b: number, c: number, d: number, e: number, f: number);
|
||||||
|
f2(1);
|
||||||
|
f2(1, 2, 3);
|
||||||
|
f2(1, 2, 3, 4, 5);
|
||||||
|
f2(1, 2, 3, 4, 5, 6, 7);
|
||||||
|
|
||||||
|
|
||||||
|
//// [functionParameterArityMismatch.js]
|
||||||
|
f1();
|
||||||
|
f1(1, 2);
|
||||||
|
f1(1, 2, 3, 4);
|
||||||
|
f2(1);
|
||||||
|
f2(1, 2, 3);
|
||||||
|
f2(1, 2, 3, 4, 5);
|
||||||
|
f2(1, 2, 3, 4, 5, 6, 7);
|
|
@ -0,0 +1,56 @@
|
||||||
|
=== tests/cases/compiler/functionParameterArityMismatch.ts ===
|
||||||
|
declare function f1(a: number);
|
||||||
|
>f1 : Symbol(f1, Decl(functionParameterArityMismatch.ts, 0, 0), Decl(functionParameterArityMismatch.ts, 0, 31))
|
||||||
|
>a : Symbol(a, Decl(functionParameterArityMismatch.ts, 0, 20))
|
||||||
|
|
||||||
|
declare function f1(a: number, b: number, c: number);
|
||||||
|
>f1 : Symbol(f1, Decl(functionParameterArityMismatch.ts, 0, 0), Decl(functionParameterArityMismatch.ts, 0, 31))
|
||||||
|
>a : Symbol(a, Decl(functionParameterArityMismatch.ts, 1, 20))
|
||||||
|
>b : Symbol(b, Decl(functionParameterArityMismatch.ts, 1, 30))
|
||||||
|
>c : Symbol(c, Decl(functionParameterArityMismatch.ts, 1, 41))
|
||||||
|
|
||||||
|
f1();
|
||||||
|
>f1 : Symbol(f1, Decl(functionParameterArityMismatch.ts, 0, 0), Decl(functionParameterArityMismatch.ts, 0, 31))
|
||||||
|
|
||||||
|
f1(1, 2);
|
||||||
|
>f1 : Symbol(f1, Decl(functionParameterArityMismatch.ts, 0, 0), Decl(functionParameterArityMismatch.ts, 0, 31))
|
||||||
|
|
||||||
|
f1(1, 2, 3, 4);
|
||||||
|
>f1 : Symbol(f1, Decl(functionParameterArityMismatch.ts, 0, 0), Decl(functionParameterArityMismatch.ts, 0, 31))
|
||||||
|
|
||||||
|
declare function f2();
|
||||||
|
>f2 : Symbol(f2, Decl(functionParameterArityMismatch.ts, 4, 15), Decl(functionParameterArityMismatch.ts, 6, 22), Decl(functionParameterArityMismatch.ts, 7, 42), Decl(functionParameterArityMismatch.ts, 8, 64))
|
||||||
|
|
||||||
|
declare function f2(a: number, b: number);
|
||||||
|
>f2 : Symbol(f2, Decl(functionParameterArityMismatch.ts, 4, 15), Decl(functionParameterArityMismatch.ts, 6, 22), Decl(functionParameterArityMismatch.ts, 7, 42), Decl(functionParameterArityMismatch.ts, 8, 64))
|
||||||
|
>a : Symbol(a, Decl(functionParameterArityMismatch.ts, 7, 20))
|
||||||
|
>b : Symbol(b, Decl(functionParameterArityMismatch.ts, 7, 30))
|
||||||
|
|
||||||
|
declare function f2(a: number, b: number, c: number, d: number);
|
||||||
|
>f2 : Symbol(f2, Decl(functionParameterArityMismatch.ts, 4, 15), Decl(functionParameterArityMismatch.ts, 6, 22), Decl(functionParameterArityMismatch.ts, 7, 42), Decl(functionParameterArityMismatch.ts, 8, 64))
|
||||||
|
>a : Symbol(a, Decl(functionParameterArityMismatch.ts, 8, 20))
|
||||||
|
>b : Symbol(b, Decl(functionParameterArityMismatch.ts, 8, 30))
|
||||||
|
>c : Symbol(c, Decl(functionParameterArityMismatch.ts, 8, 41))
|
||||||
|
>d : Symbol(d, Decl(functionParameterArityMismatch.ts, 8, 52))
|
||||||
|
|
||||||
|
declare function f2(a: number, b: number, c: number, d: number, e: number, f: number);
|
||||||
|
>f2 : Symbol(f2, Decl(functionParameterArityMismatch.ts, 4, 15), Decl(functionParameterArityMismatch.ts, 6, 22), Decl(functionParameterArityMismatch.ts, 7, 42), Decl(functionParameterArityMismatch.ts, 8, 64))
|
||||||
|
>a : Symbol(a, Decl(functionParameterArityMismatch.ts, 9, 20))
|
||||||
|
>b : Symbol(b, Decl(functionParameterArityMismatch.ts, 9, 30))
|
||||||
|
>c : Symbol(c, Decl(functionParameterArityMismatch.ts, 9, 41))
|
||||||
|
>d : Symbol(d, Decl(functionParameterArityMismatch.ts, 9, 52))
|
||||||
|
>e : Symbol(e, Decl(functionParameterArityMismatch.ts, 9, 63))
|
||||||
|
>f : Symbol(f, Decl(functionParameterArityMismatch.ts, 9, 74))
|
||||||
|
|
||||||
|
f2(1);
|
||||||
|
>f2 : Symbol(f2, Decl(functionParameterArityMismatch.ts, 4, 15), Decl(functionParameterArityMismatch.ts, 6, 22), Decl(functionParameterArityMismatch.ts, 7, 42), Decl(functionParameterArityMismatch.ts, 8, 64))
|
||||||
|
|
||||||
|
f2(1, 2, 3);
|
||||||
|
>f2 : Symbol(f2, Decl(functionParameterArityMismatch.ts, 4, 15), Decl(functionParameterArityMismatch.ts, 6, 22), Decl(functionParameterArityMismatch.ts, 7, 42), Decl(functionParameterArityMismatch.ts, 8, 64))
|
||||||
|
|
||||||
|
f2(1, 2, 3, 4, 5);
|
||||||
|
>f2 : Symbol(f2, Decl(functionParameterArityMismatch.ts, 4, 15), Decl(functionParameterArityMismatch.ts, 6, 22), Decl(functionParameterArityMismatch.ts, 7, 42), Decl(functionParameterArityMismatch.ts, 8, 64))
|
||||||
|
|
||||||
|
f2(1, 2, 3, 4, 5, 6, 7);
|
||||||
|
>f2 : Symbol(f2, Decl(functionParameterArityMismatch.ts, 4, 15), Decl(functionParameterArityMismatch.ts, 6, 22), Decl(functionParameterArityMismatch.ts, 7, 42), Decl(functionParameterArityMismatch.ts, 8, 64))
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
=== tests/cases/compiler/functionParameterArityMismatch.ts ===
|
||||||
|
declare function f1(a: number);
|
||||||
|
>f1 : { (a: number): any; (a: number, b: number, c: number): any; }
|
||||||
|
>a : number
|
||||||
|
|
||||||
|
declare function f1(a: number, b: number, c: number);
|
||||||
|
>f1 : { (a: number): any; (a: number, b: number, c: number): any; }
|
||||||
|
>a : number
|
||||||
|
>b : number
|
||||||
|
>c : number
|
||||||
|
|
||||||
|
f1();
|
||||||
|
>f1() : any
|
||||||
|
>f1 : { (a: number): any; (a: number, b: number, c: number): any; }
|
||||||
|
|
||||||
|
f1(1, 2);
|
||||||
|
>f1(1, 2) : any
|
||||||
|
>f1 : { (a: number): any; (a: number, b: number, c: number): any; }
|
||||||
|
>1 : 1
|
||||||
|
>2 : 2
|
||||||
|
|
||||||
|
f1(1, 2, 3, 4);
|
||||||
|
>f1(1, 2, 3, 4) : any
|
||||||
|
>f1 : { (a: number): any; (a: number, b: number, c: number): any; }
|
||||||
|
>1 : 1
|
||||||
|
>2 : 2
|
||||||
|
>3 : 3
|
||||||
|
>4 : 4
|
||||||
|
|
||||||
|
declare function f2();
|
||||||
|
>f2 : { (): any; (a: number, b: number): any; (a: number, b: number, c: number, d: number): any; (a: number, b: number, c: number, d: number, e: number, f: number): any; }
|
||||||
|
|
||||||
|
declare function f2(a: number, b: number);
|
||||||
|
>f2 : { (): any; (a: number, b: number): any; (a: number, b: number, c: number, d: number): any; (a: number, b: number, c: number, d: number, e: number, f: number): any; }
|
||||||
|
>a : number
|
||||||
|
>b : number
|
||||||
|
|
||||||
|
declare function f2(a: number, b: number, c: number, d: number);
|
||||||
|
>f2 : { (): any; (a: number, b: number): any; (a: number, b: number, c: number, d: number): any; (a: number, b: number, c: number, d: number, e: number, f: number): any; }
|
||||||
|
>a : number
|
||||||
|
>b : number
|
||||||
|
>c : number
|
||||||
|
>d : number
|
||||||
|
|
||||||
|
declare function f2(a: number, b: number, c: number, d: number, e: number, f: number);
|
||||||
|
>f2 : { (): any; (a: number, b: number): any; (a: number, b: number, c: number, d: number): any; (a: number, b: number, c: number, d: number, e: number, f: number): any; }
|
||||||
|
>a : number
|
||||||
|
>b : number
|
||||||
|
>c : number
|
||||||
|
>d : number
|
||||||
|
>e : number
|
||||||
|
>f : number
|
||||||
|
|
||||||
|
f2(1);
|
||||||
|
>f2(1) : any
|
||||||
|
>f2 : { (): any; (a: number, b: number): any; (a: number, b: number, c: number, d: number): any; (a: number, b: number, c: number, d: number, e: number, f: number): any; }
|
||||||
|
>1 : 1
|
||||||
|
|
||||||
|
f2(1, 2, 3);
|
||||||
|
>f2(1, 2, 3) : any
|
||||||
|
>f2 : { (): any; (a: number, b: number): any; (a: number, b: number, c: number, d: number): any; (a: number, b: number, c: number, d: number, e: number, f: number): any; }
|
||||||
|
>1 : 1
|
||||||
|
>2 : 2
|
||||||
|
>3 : 3
|
||||||
|
|
||||||
|
f2(1, 2, 3, 4, 5);
|
||||||
|
>f2(1, 2, 3, 4, 5) : any
|
||||||
|
>f2 : { (): any; (a: number, b: number): any; (a: number, b: number, c: number, d: number): any; (a: number, b: number, c: number, d: number, e: number, f: number): any; }
|
||||||
|
>1 : 1
|
||||||
|
>2 : 2
|
||||||
|
>3 : 3
|
||||||
|
>4 : 4
|
||||||
|
>5 : 5
|
||||||
|
|
||||||
|
f2(1, 2, 3, 4, 5, 6, 7);
|
||||||
|
>f2(1, 2, 3, 4, 5, 6, 7) : any
|
||||||
|
>f2 : { (): any; (a: number, b: number): any; (a: number, b: number, c: number, d: number): any; (a: number, b: number, c: number, d: number, e: number, f: number): any; }
|
||||||
|
>1 : 1
|
||||||
|
>2 : 2
|
||||||
|
>3 : 3
|
||||||
|
>4 : 4
|
||||||
|
>5 : 5
|
||||||
|
>6 : 6
|
||||||
|
>7 : 7
|
||||||
|
|
14
tests/cases/compiler/functionParameterArityMismatch.ts
Normal file
14
tests/cases/compiler/functionParameterArityMismatch.ts
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
declare function f1(a: number);
|
||||||
|
declare function f1(a: number, b: number, c: number);
|
||||||
|
f1();
|
||||||
|
f1(1, 2);
|
||||||
|
f1(1, 2, 3, 4);
|
||||||
|
|
||||||
|
declare function f2();
|
||||||
|
declare function f2(a: number, b: number);
|
||||||
|
declare function f2(a: number, b: number, c: number, d: number);
|
||||||
|
declare function f2(a: number, b: number, c: number, d: number, e: number, f: number);
|
||||||
|
f2(1);
|
||||||
|
f2(1, 2, 3);
|
||||||
|
f2(1, 2, 3, 4, 5);
|
||||||
|
f2(1, 2, 3, 4, 5, 6, 7);
|
Loading…
Reference in a new issue