Skip to content

Commit e0b3312

Browse files
committed
Merge pull request microsoft#242 from Microsoft/argumentTypeErrors
Better error messages in function calls.
2 parents c625cd9 + 155b718 commit e0b3312

110 files changed

Lines changed: 643 additions & 573 deletions

File tree

Some content is hidden

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

src/compiler/checker.ts

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3634,9 +3634,8 @@ module ts {
36343634
(!node.typeArguments || signature.typeParameters && node.typeArguments.length === signature.typeParameters.length);
36353635
}
36363636

3637-
// The candidate list is in reverse order of declaration, except that groups of signatures with the same parent are
3638-
// kept in declaration order.
3639-
function collectCandidates(node: CallExpression, signatures: Signature[]): Signature[] {
3637+
// The candidate list orders groups in reverse, but within a group signatures are kept in declaration order
3638+
function collectCandidates(node: CallExpression, signatures: Signature[]): Signature[]{
36403639
var result: Signature[] = [];
36413640
var lastParent: Node;
36423641
var pos: number;
@@ -3733,15 +3732,22 @@ module ts {
37333732
return result;
37343733
}
37353734

3736-
function isApplicableSignature(node: CallExpression, signature: Signature, relation: Map<boolean>, excludeArgument: boolean[]) {
3735+
function checkApplicableSignature(node: CallExpression, signature: Signature, relation: Map<boolean>, excludeArgument: boolean[], reportErrors: boolean) {
37373736
if (node.arguments) {
37383737
for (var i = 0; i < node.arguments.length; i++) {
37393738
var arg = node.arguments[i];
37403739
var paramType = getTypeAtPosition(signature, i);
3741-
var argType = arg.kind === SyntaxKind.StringLiteral ?
3740+
// String literals get string literal types unless we're reporting errors
3741+
var argType = arg.kind === SyntaxKind.StringLiteral && !reportErrors ?
37423742
getStringLiteralType(<LiteralExpression>arg) :
37433743
checkExpression(arg, paramType, excludeArgument && excludeArgument[i] ? identityMapper : undefined);
3744-
if (!isTypeRelatedTo(argType, paramType, relation)) return false;
3744+
// Use argument expression as error location when reporting errors
3745+
var isValidArgument = checkTypeRelatedTo(argType, paramType, relation, reportErrors ? arg : undefined,
3746+
Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1,
3747+
Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1);
3748+
if (!isValidArgument) {
3749+
return false;
3750+
}
37453751
}
37463752
}
37473753
return true;
@@ -3773,18 +3779,24 @@ module ts {
37733779
inferTypeArguments(candidate, args, excludeArgument);
37743780
candidate = getSignatureInstantiation(candidate, typeArguments);
37753781
}
3776-
if (!isApplicableSignature(node, candidate, relation, excludeArgument)) break;
3782+
if (!checkApplicableSignature(node, candidate, relation, excludeArgument, /*reportErrors*/ false)) {
3783+
break;
3784+
}
37773785
var index = excludeArgument ? indexOf(excludeArgument, true) : -1;
37783786
if (index < 0) {
37793787
return getReturnTypeOfSignature(candidate);
37803788
}
37813789
excludeArgument[index] = false;
37823790
}
37833791
}
3784-
if (relation === assignableRelation) break;
3792+
if (relation === assignableRelation) {
3793+
break;
3794+
}
37853795
relation = assignableRelation;
37863796
}
3787-
error(node, Diagnostics.Supplied_parameters_do_not_match_any_signature_of_call_target);
3797+
// No signatures were applicable. Now report errors based on the last applicable signature with
3798+
// no arguments excluded from assignability checks.
3799+
checkApplicableSignature(node, candidate, relation, undefined, /*reportErrors*/ true);
37883800
return checkErrorCall(node);
37893801
}
37903802

src/compiler/diagnosticInformationMap.generated.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ module ts {
195195
Specialized_overload_signature_is_not_assignable_to_any_non_specialized_signature: { code: 3033, category: DiagnosticCategory.Error, key: "Specialized overload signature is not assignable to any non-specialized signature." },
196196
Duplicate_function_implementation: { code: 3034, category: DiagnosticCategory.Error, key: "Duplicate function implementation." },
197197
Overload_signature_is_not_compatible_with_function_implementation: { code: 3035, category: DiagnosticCategory.Error, key: "Overload signature is not compatible with function implementation." },
198+
Argument_of_type_0_is_not_assignable_to_parameter_of_type_1: { code: 3036, category: DiagnosticCategory.Error, key: "Argument of type '{0}' is not assignable to parameter of type '{1}'." },
198199
Index_signature_is_missing_in_type_0: { code: 4003, category: DiagnosticCategory.Error, key: "Index signature is missing in type '{0}'." },
199200
Index_signatures_are_incompatible_Colon: { code: 4004, category: DiagnosticCategory.Error, key: "Index signatures are incompatible:" },
200201
Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_function: { code: 4016, category: DiagnosticCategory.NoPrefix, key: "Class '{0}' defines instance member accessor '{1}', but extended class '{2}' defines it as instance member function." },

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -772,7 +772,10 @@
772772
"category": "Error",
773773
"code": 3035
774774
},
775-
775+
"Argument of type '{0}' is not assignable to parameter of type '{1}'.": {
776+
"category": "Error",
777+
"code": 3036
778+
},
776779

777780

778781
"Index signature is missing in type '{0}'.": {

tests/baselines/reference/arrayAssignmentTest3.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212

1313
var xx = new a(null, 7, new B());
14-
~~~~~~~~~~~~~~~~~~~~~~~
15-
!!! Supplied parameters do not match any signature of call target.
14+
~~~~~~~
15+
!!! Argument of type 'B' is not assignable to parameter of type 'B[]'.
1616

1717

tests/baselines/reference/arrayLiteralContextualType.errors.txt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@
2727

2828
var arr = [new Giraffe(), new Elephant()];
2929
foo(arr); // Error because of no contextual type
30-
~~~~~~~~
31-
!!! Supplied parameters do not match any signature of call target.
30+
~~~
31+
!!! Argument of type '{}[]' is not assignable to parameter of type 'IAnimal[]'.
32+
!!! Type '{}' is not assignable to type 'IAnimal'.
3233
bar(arr); // Error because of no contextual type
33-
~~~~~~~~
34-
!!! Supplied parameters do not match any signature of call target.
34+
~~~
35+
!!! Argument of type '{}[]' is not assignable to parameter of type '{ [x: number]: IAnimal; }'.

tests/baselines/reference/assignLambdaToNominalSubtypeOfFunction.errors.txt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
function fn(cb: IResultCallback) { }
77

88
fn((a, b) => true);
9-
~~~~~~~~~~~~~~~~~~
10-
!!! Supplied parameters do not match any signature of call target.
9+
~~~~~~~~~~~~~~
10+
!!! Argument of type '(a: any, b: any) => boolean' is not assignable to parameter of type 'IResultCallback'.
11+
!!! Property 'x' is missing in type '(a: any, b: any) => boolean'.
1112
fn(function (a, b) { return true; })
12-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
13-
!!! Supplied parameters do not match any signature of call target.
13+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
14+
!!! Argument of type '(a: any, b: any) => boolean' is not assignable to parameter of type 'IResultCallback'.
15+
!!! Property 'x' is missing in type '(a: any, b: any) => boolean'.
1416

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
==== tests/cases/compiler/assignmentCompatBug5.ts (4 errors) ====
22
function foo1(x: { a: number; }) { }
33
foo1({ b: 5 });
4-
~~~~~~~~~~~~~~
5-
!!! Supplied parameters do not match any signature of call target.
4+
~~~~~~~~
5+
!!! Argument of type '{ b: number; }' is not assignable to parameter of type '{ a: number; }'.
6+
!!! Property 'a' is missing in type '{ b: number; }'.
67

78
function foo2(x: number[]) { }
89
foo2(["s", "t"]);
9-
~~~~~~~~~~~~~~~~
10-
!!! Supplied parameters do not match any signature of call target.
10+
~~~~~~~~~~
11+
!!! Argument of type 'string[]' is not assignable to parameter of type 'number[]'.
12+
!!! Type 'string' is not assignable to type 'number'.
1113

1214
function foo3(x: (n: number) =>number) { };
1315
foo3((s:string) => { });
14-
~~~~~~~~~~~~~~~~~~~~~~~
15-
!!! Supplied parameters do not match any signature of call target.
16+
~~~~~~~~~~~~~~~~~
17+
!!! Argument of type '(s: string) => void' is not assignable to parameter of type '(n: number) => number'.
1618
foo3((n) => { return; });
17-
~~~~~~~~~~~~~~~~~~~~~~~~
18-
!!! Supplied parameters do not match any signature of call target.
19+
~~~~~~~~~~~~~~~~~~
20+
!!! Argument of type '(n: number) => void' is not assignable to parameter of type '(n: number) => number'.
1921

2022

tests/baselines/reference/assignmentCompatFunctionsWithOptionalArgs.errors.txt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,11 @@
55
foo({ id: 1234 }); // Ok
66
foo({ id: 1234, name: "hello" }); // Ok
77
foo({ id: 1234, name: false }); // Error, name of wrong type
8-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9-
!!! Supplied parameters do not match any signature of call target.
8+
~~~~~~~~~~~~~~~~~~~~~~~~~
9+
!!! Argument of type '{ id: number; name: boolean; }' is not assignable to parameter of type '{ id: number; name?: string; }'.
10+
!!! Types of property 'name' are incompatible:
11+
!!! Type 'boolean' is not assignable to type 'string'.
1012
foo({ name: "hello" }); // Error, id required but missing
11-
~~~~~~~~~~~~~~~~~~~~~~
12-
!!! Supplied parameters do not match any signature of call target.
13+
~~~~~~~~~~~~~~~~~
14+
!!! Argument of type '{ name: string; }' is not assignable to parameter of type '{ id: number; name?: string; }'.
15+
!!! Property 'id' is missing in type '{ name: string; }'.

tests/baselines/reference/assignmentCompatInterfaceWithStringIndexSignature.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@
1414
function Biz(map: IHandlerMap) { }
1515

1616
Biz(new Foo());
17-
~~~~~~~~~~~~~~
18-
!!! Supplied parameters do not match any signature of call target.
17+
~~~~~~~~~
18+
!!! Argument of type 'Foo' is not assignable to parameter of type 'IHandlerMap'.
1919

tests/baselines/reference/assignmentCompatability_checking-apply-member-off-of-function-interface.errors.txt

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,18 @@
3333

3434
// Should Fail
3535
fn('');
36-
~~~~~~
37-
!!! Supplied parameters do not match any signature of call target.
36+
~~
37+
!!! Argument of type 'string' is not assignable to parameter of type 'Applicable'.
3838
fn(['']);
39-
~~~~~~~~
40-
!!! Supplied parameters do not match any signature of call target.
39+
~~~~
40+
!!! Argument of type 'string[]' is not assignable to parameter of type 'Applicable'.
4141
fn(4);
42-
~~~~~
43-
!!! Supplied parameters do not match any signature of call target.
42+
~
43+
!!! Argument of type 'number' is not assignable to parameter of type 'Applicable'.
4444
fn({});
45-
~~~~~~
46-
!!! Supplied parameters do not match any signature of call target.
45+
~~
46+
!!! Argument of type '{}' is not assignable to parameter of type 'Applicable'.
47+
!!! Property 'apply' is missing in type '{}'.
4748

4849

4950
// Should work

0 commit comments

Comments
 (0)