Skip to content

Commit e6aa992

Browse files
Philip Pescasandersn
authored andcommitted
Fix error message when type argument arity is wrong (microsoft#28366)
* Fix error message when type argument arity is wrong * Parenthesize 's' in plurals * Update baseline * Update baseline * Use old error message * Revert parantheses
1 parent 3c408d8 commit e6aa992

11 files changed

+298
-16
lines changed

src/compiler/checker.ts

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19890,14 +19890,31 @@ namespace ts {
1989019890
}
1989119891

1989219892
function getTypeArgumentArityError(node: Node, signatures: ReadonlyArray<Signature>, typeArguments: NodeArray<TypeNode>) {
19893-
let min = Infinity;
19894-
let max = -Infinity;
19893+
const argCount = typeArguments.length;
19894+
// No overloads exist
19895+
if (signatures.length === 1) {
19896+
const sig = signatures[0];
19897+
const min = getMinTypeArgumentCount(sig.typeParameters);
19898+
const max = length(sig.typeParameters);
19899+
return createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.Expected_0_type_arguments_but_got_1, min < max ? min + "-" + max : min , argCount);
19900+
}
19901+
// Overloads exist
19902+
let belowArgCount = -Infinity;
19903+
let aboveArgCount = Infinity;
1989519904
for (const sig of signatures) {
19896-
min = Math.min(min, getMinTypeArgumentCount(sig.typeParameters));
19897-
max = Math.max(max, length(sig.typeParameters));
19905+
const min = getMinTypeArgumentCount(sig.typeParameters);
19906+
const max = length(sig.typeParameters);
19907+
if (min > argCount) {
19908+
aboveArgCount = Math.min(aboveArgCount, min);
19909+
}
19910+
else if (max < argCount) {
19911+
belowArgCount = Math.max(belowArgCount, max);
19912+
}
19913+
}
19914+
if (belowArgCount !== -Infinity && aboveArgCount !== Infinity) {
19915+
return createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.No_overload_expects_0_type_arguments_but_overloads_do_exist_that_expect_either_1_or_2_type_arguments, argCount, belowArgCount, aboveArgCount);
1989819916
}
19899-
const paramCount = min === max ? min : min + "-" + max;
19900-
return createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.Expected_0_type_arguments_but_got_1, paramCount, typeArguments.length);
19917+
return createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.Expected_0_type_arguments_but_got_1, belowArgCount === -Infinity ? aboveArgCount : belowArgCount, argCount);
1990119918
}
1990219919

1990319920
function resolveCall(node: CallLikeExpression, signatures: ReadonlyArray<Signature>, candidatesOutArray: Signature[] | undefined, isForSignatureHelp: boolean, fallbackError?: DiagnosticMessage): Signature {

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2533,6 +2533,10 @@
25332533
"category": "Error",
25342534
"code": 2742
25352535
},
2536+
"No overload expects {0} type arguments, but overloads do exist that expect either {1} or {2} type arguments.": {
2537+
"category": "Error",
2538+
"code": 2743
2539+
},
25362540

25372541
"Import declaration '{0}' is using private name '{1}'.": {
25382542
"category": "Error",
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
tests/cases/compiler/functionTypeArgumentArityErrors.ts(4,4): error TS2743: No overload expects 2 type arguments, but overloads do exist that expect either 1 or 3 type arguments.
2+
tests/cases/compiler/functionTypeArgumentArityErrors.ts(5,4): error TS2558: Expected 4 type arguments, but got 5.
3+
tests/cases/compiler/functionTypeArgumentArityErrors.ts(10,4): error TS2743: No overload expects 2 type arguments, but overloads do exist that expect either 1 or 3 type arguments.
4+
tests/cases/compiler/functionTypeArgumentArityErrors.ts(11,4): error TS2558: Expected 3 type arguments, but got 4.
5+
tests/cases/compiler/functionTypeArgumentArityErrors.ts(16,4): error TS2558: Expected 0 type arguments, but got 1.
6+
tests/cases/compiler/functionTypeArgumentArityErrors.ts(20,4): error TS2558: Expected 2-3 type arguments, but got 1.
7+
tests/cases/compiler/functionTypeArgumentArityErrors.ts(21,4): error TS2558: Expected 2-3 type arguments, but got 4.
8+
tests/cases/compiler/functionTypeArgumentArityErrors.ts(25,4): error TS2558: Expected 2 type arguments, but got 1.
9+
tests/cases/compiler/functionTypeArgumentArityErrors.ts(26,4): error TS2558: Expected 2 type arguments, but got 3.
10+
11+
12+
==== tests/cases/compiler/functionTypeArgumentArityErrors.ts (9 errors) ====
13+
// Overloaded functions with default type arguments
14+
declare function f1<A = any>(): void;
15+
declare function f1<A, B, C, D = any>(): void;
16+
f1<number, number>();
17+
~~~~~~~~~~~~~~
18+
!!! error TS2743: No overload expects 2 type arguments, but overloads do exist that expect either 1 or 3 type arguments.
19+
f1<number, number, number, number, number>();
20+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
21+
!!! error TS2558: Expected 4 type arguments, but got 5.
22+
23+
// Overloaded functions with no default type arguments
24+
declare function f2<A>(): void;
25+
declare function f2<A, B, C>(): void;
26+
f2<number, number>();
27+
~~~~~~~~~~~~~~
28+
!!! error TS2743: No overload expects 2 type arguments, but overloads do exist that expect either 1 or 3 type arguments.
29+
f2<number, number, number, number>();
30+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
31+
!!! error TS2558: Expected 3 type arguments, but got 4.
32+
33+
// Overloaded non-generic functions
34+
declare function f3(): void;
35+
declare function f3(a): void;
36+
f3<number>();
37+
~~~~~~
38+
!!! error TS2558: Expected 0 type arguments, but got 1.
39+
40+
// Generic function with default type parameters
41+
declare function f4<A, B, C = any>(): void;
42+
f4<number>();
43+
~~~~~~
44+
!!! error TS2558: Expected 2-3 type arguments, but got 1.
45+
f4<number, number, number, number>();
46+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
47+
!!! error TS2558: Expected 2-3 type arguments, but got 4.
48+
49+
// Generic function with no default type arguments
50+
declare function f5<A, B>(): void;
51+
f5<number>();
52+
~~~~~~
53+
!!! error TS2558: Expected 2 type arguments, but got 1.
54+
f5<number, number, number>();
55+
~~~~~~~~~~~~~~~~~~~~~~
56+
!!! error TS2558: Expected 2 type arguments, but got 3.
57+
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//// [functionTypeArgumentArityErrors.ts]
2+
// Overloaded functions with default type arguments
3+
declare function f1<A = any>(): void;
4+
declare function f1<A, B, C, D = any>(): void;
5+
f1<number, number>();
6+
f1<number, number, number, number, number>();
7+
8+
// Overloaded functions with no default type arguments
9+
declare function f2<A>(): void;
10+
declare function f2<A, B, C>(): void;
11+
f2<number, number>();
12+
f2<number, number, number, number>();
13+
14+
// Overloaded non-generic functions
15+
declare function f3(): void;
16+
declare function f3(a): void;
17+
f3<number>();
18+
19+
// Generic function with default type parameters
20+
declare function f4<A, B, C = any>(): void;
21+
f4<number>();
22+
f4<number, number, number, number>();
23+
24+
// Generic function with no default type arguments
25+
declare function f5<A, B>(): void;
26+
f5<number>();
27+
f5<number, number, number>();
28+
29+
30+
//// [functionTypeArgumentArityErrors.js]
31+
f1();
32+
f1();
33+
f2();
34+
f2();
35+
f3();
36+
f4();
37+
f4();
38+
f5();
39+
f5();
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
=== tests/cases/compiler/functionTypeArgumentArityErrors.ts ===
2+
// Overloaded functions with default type arguments
3+
declare function f1<A = any>(): void;
4+
>f1 : Symbol(f1, Decl(functionTypeArgumentArityErrors.ts, 0, 0), Decl(functionTypeArgumentArityErrors.ts, 1, 37))
5+
>A : Symbol(A, Decl(functionTypeArgumentArityErrors.ts, 1, 20))
6+
7+
declare function f1<A, B, C, D = any>(): void;
8+
>f1 : Symbol(f1, Decl(functionTypeArgumentArityErrors.ts, 0, 0), Decl(functionTypeArgumentArityErrors.ts, 1, 37))
9+
>A : Symbol(A, Decl(functionTypeArgumentArityErrors.ts, 2, 20))
10+
>B : Symbol(B, Decl(functionTypeArgumentArityErrors.ts, 2, 22))
11+
>C : Symbol(C, Decl(functionTypeArgumentArityErrors.ts, 2, 25))
12+
>D : Symbol(D, Decl(functionTypeArgumentArityErrors.ts, 2, 28))
13+
14+
f1<number, number>();
15+
>f1 : Symbol(f1, Decl(functionTypeArgumentArityErrors.ts, 0, 0), Decl(functionTypeArgumentArityErrors.ts, 1, 37))
16+
17+
f1<number, number, number, number, number>();
18+
>f1 : Symbol(f1, Decl(functionTypeArgumentArityErrors.ts, 0, 0), Decl(functionTypeArgumentArityErrors.ts, 1, 37))
19+
20+
// Overloaded functions with no default type arguments
21+
declare function f2<A>(): void;
22+
>f2 : Symbol(f2, Decl(functionTypeArgumentArityErrors.ts, 4, 45), Decl(functionTypeArgumentArityErrors.ts, 7, 31))
23+
>A : Symbol(A, Decl(functionTypeArgumentArityErrors.ts, 7, 20))
24+
25+
declare function f2<A, B, C>(): void;
26+
>f2 : Symbol(f2, Decl(functionTypeArgumentArityErrors.ts, 4, 45), Decl(functionTypeArgumentArityErrors.ts, 7, 31))
27+
>A : Symbol(A, Decl(functionTypeArgumentArityErrors.ts, 8, 20))
28+
>B : Symbol(B, Decl(functionTypeArgumentArityErrors.ts, 8, 22))
29+
>C : Symbol(C, Decl(functionTypeArgumentArityErrors.ts, 8, 25))
30+
31+
f2<number, number>();
32+
>f2 : Symbol(f2, Decl(functionTypeArgumentArityErrors.ts, 4, 45), Decl(functionTypeArgumentArityErrors.ts, 7, 31))
33+
34+
f2<number, number, number, number>();
35+
>f2 : Symbol(f2, Decl(functionTypeArgumentArityErrors.ts, 4, 45), Decl(functionTypeArgumentArityErrors.ts, 7, 31))
36+
37+
// Overloaded non-generic functions
38+
declare function f3(): void;
39+
>f3 : Symbol(f3, Decl(functionTypeArgumentArityErrors.ts, 10, 37), Decl(functionTypeArgumentArityErrors.ts, 13, 28))
40+
41+
declare function f3(a): void;
42+
>f3 : Symbol(f3, Decl(functionTypeArgumentArityErrors.ts, 10, 37), Decl(functionTypeArgumentArityErrors.ts, 13, 28))
43+
>a : Symbol(a, Decl(functionTypeArgumentArityErrors.ts, 14, 20))
44+
45+
f3<number>();
46+
>f3 : Symbol(f3, Decl(functionTypeArgumentArityErrors.ts, 10, 37), Decl(functionTypeArgumentArityErrors.ts, 13, 28))
47+
48+
// Generic function with default type parameters
49+
declare function f4<A, B, C = any>(): void;
50+
>f4 : Symbol(f4, Decl(functionTypeArgumentArityErrors.ts, 15, 13))
51+
>A : Symbol(A, Decl(functionTypeArgumentArityErrors.ts, 18, 20))
52+
>B : Symbol(B, Decl(functionTypeArgumentArityErrors.ts, 18, 22))
53+
>C : Symbol(C, Decl(functionTypeArgumentArityErrors.ts, 18, 25))
54+
55+
f4<number>();
56+
>f4 : Symbol(f4, Decl(functionTypeArgumentArityErrors.ts, 15, 13))
57+
58+
f4<number, number, number, number>();
59+
>f4 : Symbol(f4, Decl(functionTypeArgumentArityErrors.ts, 15, 13))
60+
61+
// Generic function with no default type arguments
62+
declare function f5<A, B>(): void;
63+
>f5 : Symbol(f5, Decl(functionTypeArgumentArityErrors.ts, 20, 37))
64+
>A : Symbol(A, Decl(functionTypeArgumentArityErrors.ts, 23, 20))
65+
>B : Symbol(B, Decl(functionTypeArgumentArityErrors.ts, 23, 22))
66+
67+
f5<number>();
68+
>f5 : Symbol(f5, Decl(functionTypeArgumentArityErrors.ts, 20, 37))
69+
70+
f5<number, number, number>();
71+
>f5 : Symbol(f5, Decl(functionTypeArgumentArityErrors.ts, 20, 37))
72+
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
=== tests/cases/compiler/functionTypeArgumentArityErrors.ts ===
2+
// Overloaded functions with default type arguments
3+
declare function f1<A = any>(): void;
4+
>f1 : { <A = any>(): void; <A, B, C, D = any>(): void; }
5+
6+
declare function f1<A, B, C, D = any>(): void;
7+
>f1 : { <A = any>(): void; <A, B, C, D = any>(): void; }
8+
9+
f1<number, number>();
10+
>f1<number, number>() : any
11+
>f1 : { <A = any>(): void; <A, B, C, D = any>(): void; }
12+
13+
f1<number, number, number, number, number>();
14+
>f1<number, number, number, number, number>() : any
15+
>f1 : { <A = any>(): void; <A, B, C, D = any>(): void; }
16+
17+
// Overloaded functions with no default type arguments
18+
declare function f2<A>(): void;
19+
>f2 : { <A>(): void; <A, B, C>(): void; }
20+
21+
declare function f2<A, B, C>(): void;
22+
>f2 : { <A>(): void; <A, B, C>(): void; }
23+
24+
f2<number, number>();
25+
>f2<number, number>() : any
26+
>f2 : { <A>(): void; <A, B, C>(): void; }
27+
28+
f2<number, number, number, number>();
29+
>f2<number, number, number, number>() : any
30+
>f2 : { <A>(): void; <A, B, C>(): void; }
31+
32+
// Overloaded non-generic functions
33+
declare function f3(): void;
34+
>f3 : { (): void; (a: any): void; }
35+
36+
declare function f3(a): void;
37+
>f3 : { (): void; (a: any): void; }
38+
>a : any
39+
40+
f3<number>();
41+
>f3<number>() : any
42+
>f3 : { (): void; (a: any): void; }
43+
44+
// Generic function with default type parameters
45+
declare function f4<A, B, C = any>(): void;
46+
>f4 : <A, B, C = any>() => void
47+
48+
f4<number>();
49+
>f4<number>() : any
50+
>f4 : <A, B, C = any>() => void
51+
52+
f4<number, number, number, number>();
53+
>f4<number, number, number, number>() : any
54+
>f4 : <A, B, C = any>() => void
55+
56+
// Generic function with no default type arguments
57+
declare function f5<A, B>(): void;
58+
>f5 : <A, B>() => void
59+
60+
f5<number>();
61+
>f5<number>() : any
62+
>f5 : <A, B>() => void
63+
64+
f5<number, number, number>();
65+
>f5<number, number, number>() : any
66+
>f5 : <A, B>() => void
67+
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
tests/cases/compiler/newMap.ts(1,9): error TS2558: Expected 0-2 type arguments, but got 1.
1+
tests/cases/compiler/newMap.ts(1,9): error TS2743: No overload expects 1 type arguments, but overloads do exist that expect either 0 or 2 type arguments.
22

33

44
==== tests/cases/compiler/newMap.ts (1 errors) ====
55
new Map<string>();
66
~~~~~~
7-
!!! error TS2558: Expected 0-2 type arguments, but got 1.
7+
!!! error TS2743: No overload expects 1 type arguments, but overloads do exist that expect either 0 or 2 type arguments.
88

tests/baselines/reference/overloadResolution.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
tests/cases/conformance/expressions/functionCalls/overloadResolution.ts(27,5): error TS2345: Argument of type '{}' is not assignable to parameter of type 'number'.
22
tests/cases/conformance/expressions/functionCalls/overloadResolution.ts(41,11): error TS2345: Argument of type '""' is not assignable to parameter of type 'number'.
3-
tests/cases/conformance/expressions/functionCalls/overloadResolution.ts(63,5): error TS2558: Expected 1-3 type arguments, but got 4.
3+
tests/cases/conformance/expressions/functionCalls/overloadResolution.ts(63,5): error TS2558: Expected 3 type arguments, but got 4.
44
tests/cases/conformance/expressions/functionCalls/overloadResolution.ts(70,21): error TS2345: Argument of type '3' is not assignable to parameter of type 'string'.
55
tests/cases/conformance/expressions/functionCalls/overloadResolution.ts(71,21): error TS2345: Argument of type '""' is not assignable to parameter of type 'number'.
66
tests/cases/conformance/expressions/functionCalls/overloadResolution.ts(81,5): error TS2344: Type 'boolean' does not satisfy the constraint 'number'.
@@ -79,7 +79,7 @@ tests/cases/conformance/expressions/functionCalls/overloadResolution.ts(91,22):
7979
// Generic overloads with differing arity called with type argument count that doesn't match any overload
8080
fn3<number, number, number, number>(); // Error
8181
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
82-
!!! error TS2558: Expected 1-3 type arguments, but got 4.
82+
!!! error TS2558: Expected 3 type arguments, but got 4.
8383

8484
// Generic overloads with constraints called with type arguments that satisfy the constraints
8585
function fn4<T extends string, U extends number>(n: T, m: U);

tests/baselines/reference/overloadResolutionConstructors.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
tests/cases/conformance/expressions/functionCalls/overloadResolutionConstructors.ts(27,9): error TS2345: Argument of type '{}' is not assignable to parameter of type 'number'.
22
tests/cases/conformance/expressions/functionCalls/overloadResolutionConstructors.ts(43,15): error TS2345: Argument of type '""' is not assignable to parameter of type 'number'.
3-
tests/cases/conformance/expressions/functionCalls/overloadResolutionConstructors.ts(67,9): error TS2558: Expected 1-3 type arguments, but got 4.
3+
tests/cases/conformance/expressions/functionCalls/overloadResolutionConstructors.ts(67,9): error TS2558: Expected 3 type arguments, but got 4.
44
tests/cases/conformance/expressions/functionCalls/overloadResolutionConstructors.ts(77,25): error TS2345: Argument of type '3' is not assignable to parameter of type 'string'.
55
tests/cases/conformance/expressions/functionCalls/overloadResolutionConstructors.ts(78,25): error TS2345: Argument of type '""' is not assignable to parameter of type 'number'.
66
tests/cases/conformance/expressions/functionCalls/overloadResolutionConstructors.ts(88,9): error TS2344: Type 'boolean' does not satisfy the constraint 'number'.
@@ -83,7 +83,7 @@ tests/cases/conformance/expressions/functionCalls/overloadResolutionConstructors
8383
// Generic overloads with differing arity called with type argument count that doesn't match any overload
8484
new fn3<number, number, number, number>(); // Error
8585
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
86-
!!! error TS2558: Expected 1-3 type arguments, but got 4.
86+
!!! error TS2558: Expected 3 type arguments, but got 4.
8787

8888
// Generic overloads with constraints called with type arguments that satisfy the constraints
8989
interface fn4 {

tests/baselines/reference/overloadsAndTypeArgumentArityErrors.errors.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
tests/cases/compiler/overloadsAndTypeArgumentArityErrors.ts(5,11): error TS2558: Expected 0-2 type arguments, but got 3.
2-
tests/cases/compiler/overloadsAndTypeArgumentArityErrors.ts(6,15): error TS2558: Expected 0-2 type arguments, but got 3.
1+
tests/cases/compiler/overloadsAndTypeArgumentArityErrors.ts(5,11): error TS2558: Expected 2 type arguments, but got 3.
2+
tests/cases/compiler/overloadsAndTypeArgumentArityErrors.ts(6,15): error TS2558: Expected 2 type arguments, but got 3.
33
tests/cases/compiler/overloadsAndTypeArgumentArityErrors.ts(9,1): error TS2554: Expected 1 arguments, but got 0.
44

55

@@ -10,10 +10,10 @@ tests/cases/compiler/overloadsAndTypeArgumentArityErrors.ts(9,1): error TS2554:
1010

1111
Callbacks<number, string, boolean>('s'); // wrong number of type arguments
1212
~~~~~~~~~~~~~~~~~~~~~~~
13-
!!! error TS2558: Expected 0-2 type arguments, but got 3.
13+
!!! error TS2558: Expected 2 type arguments, but got 3.
1414
new Callbacks<number, string, boolean>('s'); // wrong number of type arguments
1515
~~~~~~~~~~~~~~~~~~~~~~~
16-
!!! error TS2558: Expected 0-2 type arguments, but got 3.
16+
!!! error TS2558: Expected 2 type arguments, but got 3.
1717

1818
declare function f<A, B = {}>(arg: number): void;
1919
f<number>(); // wrong number of arguments (#25683)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Overloaded functions with default type arguments
2+
declare function f1<A = any>(): void;
3+
declare function f1<A, B, C, D = any>(): void;
4+
f1<number, number>();
5+
f1<number, number, number, number, number>();
6+
7+
// Overloaded functions with no default type arguments
8+
declare function f2<A>(): void;
9+
declare function f2<A, B, C>(): void;
10+
f2<number, number>();
11+
f2<number, number, number, number>();
12+
13+
// Overloaded non-generic functions
14+
declare function f3(): void;
15+
declare function f3(a): void;
16+
f3<number>();
17+
18+
// Generic function with default type parameters
19+
declare function f4<A, B, C = any>(): void;
20+
f4<number>();
21+
f4<number, number, number, number>();
22+
23+
// Generic function with no default type arguments
24+
declare function f5<A, B>(): void;
25+
f5<number>();
26+
f5<number, number, number>();

0 commit comments

Comments
 (0)