Skip to content

Commit c3092ef

Browse files
committed
Use signature result type in call exprs even when argument types mismatch
Fixes microsoft#6992
1 parent 98a2458 commit c3092ef

21 files changed

+132
-49
lines changed

src/compiler/checker.ts

+19-13
Original file line numberDiff line numberDiff line change
@@ -9330,8 +9330,14 @@ namespace ts {
93309330
return anySignature;
93319331
}
93329332

9333-
function resolveErrorCall(node: CallLikeExpression): Signature {
9333+
function resolveErrorCall(node: CallLikeExpression, candidates: Signature[]): Signature {
93349334
resolveUntypedCall(node);
9335+
if (candidates && candidates.length > 0) {
9336+
const last = candidates[candidates.length - 1];
9337+
if (!last.typeParameters) {
9338+
return last;
9339+
}
9340+
}
93359341
return unknownSignature;
93369342
}
93379343

@@ -9954,7 +9960,7 @@ namespace ts {
99549960
reorderCandidates(signatures, candidates);
99559961
if (!candidates.length) {
99569962
reportError(Diagnostics.Supplied_parameters_do_not_match_any_signature_of_call_target);
9957-
return resolveErrorCall(node);
9963+
return resolveErrorCall(node, signatures);
99589964
}
99599965

99609966
const args = getEffectiveCallArguments(node);
@@ -10090,7 +10096,7 @@ namespace ts {
1009010096
}
1009110097
}
1009210098

10093-
return resolveErrorCall(node);
10099+
return resolveErrorCall(node, signatures);
1009410100

1009510101
function reportError(message: DiagnosticMessage, arg0?: string, arg1?: string, arg2?: string): void {
1009610102
let errorInfo: DiagnosticMessageChain;
@@ -10190,7 +10196,7 @@ namespace ts {
1019010196

1019110197
if (apparentType === unknownType) {
1019210198
// Another error has already been reported
10193-
return resolveErrorCall(node);
10199+
return resolveErrorCall(node, /*candidates*/ undefined);
1019410200
}
1019510201

1019610202
// Technically, this signatures list may be incomplete. We are taking the apparent type,
@@ -10225,7 +10231,7 @@ namespace ts {
1022510231
else {
1022610232
error(node, Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature);
1022710233
}
10228-
return resolveErrorCall(node);
10234+
return resolveErrorCall(node, constructSignatures);
1022910235
}
1023010236
return resolveCall(node, callSignatures, candidatesOutArray);
1023110237
}
@@ -10248,7 +10254,7 @@ namespace ts {
1024810254
expressionType = getApparentType(expressionType);
1024910255
if (expressionType === unknownType) {
1025010256
// Another error has already been reported
10251-
return resolveErrorCall(node);
10257+
return resolveErrorCall(node, /*candidates*/ undefined);
1025210258
}
1025310259

1025410260
// If the expression is a class of abstract type, then it cannot be instantiated.
@@ -10258,7 +10264,7 @@ namespace ts {
1025810264
const valueDecl = expressionType.symbol && getClassLikeDeclarationOfSymbol(expressionType.symbol);
1025910265
if (valueDecl && valueDecl.flags & NodeFlags.Abstract) {
1026010266
error(node, Diagnostics.Cannot_create_an_instance_of_the_abstract_class_0, declarationNameToString(valueDecl.name));
10261-
return resolveErrorCall(node);
10267+
return resolveErrorCall(node, /*candidates*/ undefined);
1026210268
}
1026310269

1026410270
// TS 1.0 spec: 4.11
@@ -10278,7 +10284,7 @@ namespace ts {
1027810284
const constructSignatures = getSignaturesOfType(expressionType, SignatureKind.Construct);
1027910285
if (constructSignatures.length) {
1028010286
if (!isConstructorAccessible(node, constructSignatures[0])) {
10281-
return resolveErrorCall(node);
10287+
return resolveErrorCall(node, constructSignatures);
1028210288
}
1028310289
return resolveCall(node, constructSignatures, candidatesOutArray);
1028410290
}
@@ -10297,7 +10303,7 @@ namespace ts {
1029710303
}
1029810304

1029910305
error(node, Diagnostics.Cannot_use_new_with_an_expression_whose_type_lacks_a_call_or_construct_signature);
10300-
return resolveErrorCall(node);
10306+
return resolveErrorCall(node, callSignatures);
1030110307
}
1030210308

1030310309
function isConstructorAccessible(node: NewExpression, signature: Signature) {
@@ -10336,7 +10342,7 @@ namespace ts {
1033610342

1033710343
if (apparentType === unknownType) {
1033810344
// Another error has already been reported
10339-
return resolveErrorCall(node);
10345+
return resolveErrorCall(node, /*candidates*/ undefined);
1034010346
}
1034110347

1034210348
const callSignatures = getSignaturesOfType(apparentType, SignatureKind.Call);
@@ -10347,7 +10353,7 @@ namespace ts {
1034710353

1034810354
if (!callSignatures.length) {
1034910355
error(node, Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature);
10350-
return resolveErrorCall(node);
10356+
return resolveErrorCall(node, /*candidates*/ undefined);
1035110357
}
1035210358

1035310359
return resolveCall(node, callSignatures, candidatesOutArray);
@@ -10382,7 +10388,7 @@ namespace ts {
1038210388
const funcType = checkExpression(node.expression);
1038310389
const apparentType = getApparentType(funcType);
1038410390
if (apparentType === unknownType) {
10385-
return resolveErrorCall(node);
10391+
return resolveErrorCall(node, /*candidates*/ undefined);
1038610392
}
1038710393

1038810394
const callSignatures = getSignaturesOfType(apparentType, SignatureKind.Call);
@@ -10396,7 +10402,7 @@ namespace ts {
1039610402
errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature);
1039710403
errorInfo = chainDiagnosticMessages(errorInfo, headMessage);
1039810404
diagnostics.add(createDiagnosticForNodeFromMessageChain(node, errorInfo));
10399-
return resolveErrorCall(node);
10405+
return resolveErrorCall(node, callSignatures);
1040010406
}
1040110407

1040210408
return resolveCall(node, callSignatures, candidatesOutArray, headMessage);

tests/baselines/reference/classConstructorAccessibility.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ declare class E {
9797
protected constructor(x: number);
9898
}
9999
declare var c: C;
100-
declare var d: any;
101-
declare var e: any;
100+
declare var d: D;
101+
declare var e: E;
102102
declare module Generic {
103103
}

tests/baselines/reference/classConstructorAccessibility2.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,8 @@ declare class DerivedC extends BaseC {
141141
createBaseInstance(): void;
142142
}
143143
declare var ba: BaseA;
144-
declare var bb: any;
145-
declare var bc: any;
144+
declare var bb: BaseB;
145+
declare var bc: BaseC;
146146
declare var da: DerivedA;
147147
declare var db: DerivedB;
148148
declare var dc: DerivedC;

tests/baselines/reference/constructorOverloads1.errors.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ tests/cases/compiler/constructorOverloads1.ts(3,5): error TS2392: Multiple const
33
tests/cases/compiler/constructorOverloads1.ts(4,5): error TS2392: Multiple constructor implementations are not allowed.
44
tests/cases/compiler/constructorOverloads1.ts(7,5): error TS2392: Multiple constructor implementations are not allowed.
55
tests/cases/compiler/constructorOverloads1.ts(16,18): error TS2345: Argument of type 'Foo' is not assignable to parameter of type 'number'.
6-
tests/cases/compiler/constructorOverloads1.ts(17,18): error TS2345: Argument of type 'any[]' is not assignable to parameter of type 'number'.
6+
tests/cases/compiler/constructorOverloads1.ts(17,18): error TS2345: Argument of type 'Foo[]' is not assignable to parameter of type 'number'.
77

88

99
==== tests/cases/compiler/constructorOverloads1.ts (6 errors) ====
@@ -39,7 +39,7 @@ tests/cases/compiler/constructorOverloads1.ts(17,18): error TS2345: Argument of
3939
!!! error TS2345: Argument of type 'Foo' is not assignable to parameter of type 'number'.
4040
var f4 = new Foo([f1,f2,f3]);
4141
~~~~~~~~~~
42-
!!! error TS2345: Argument of type 'any[]' is not assignable to parameter of type 'number'.
42+
!!! error TS2345: Argument of type 'Foo[]' is not assignable to parameter of type 'number'.
4343

4444
f1.bar1();
4545
f1.bar2();
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
1+
tests/cases/conformance/decorators/class/property/decoratorOnClassProperty11.ts(4,5): error TS1236: The return type of a property decorator function must be either 'void' or 'any'.
2+
Unable to resolve signature of property decorator when called as an expression.
13
tests/cases/conformance/decorators/class/property/decoratorOnClassProperty11.ts(4,5): error TS1240: Unable to resolve signature of property decorator when called as an expression.
24
Supplied parameters do not match any signature of call target.
35

46

5-
==== tests/cases/conformance/decorators/class/property/decoratorOnClassProperty11.ts (1 errors) ====
7+
==== tests/cases/conformance/decorators/class/property/decoratorOnClassProperty11.ts (2 errors) ====
68
declare function dec(): <T>(target: any, propertyKey: string) => void;
79

810
class C {
911
@dec prop;
1012
~~~~
13+
!!! error TS1236: The return type of a property decorator function must be either 'void' or 'any'.
14+
!!! error TS1236: Unable to resolve signature of property decorator when called as an expression.
15+
~~~~
1116
!!! error TS1240: Unable to resolve signature of property decorator when called as an expression.
1217
!!! error TS1240: Supplied parameters do not match any signature of call target.
1318
}

tests/baselines/reference/defaultArgsInFunctionExpressions.errors.txt

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
tests/cases/compiler/defaultArgsInFunctionExpressions.ts(4,5): error TS2322: Type 'number' is not assignable to type 'string'.
12
tests/cases/compiler/defaultArgsInFunctionExpressions.ts(4,19): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
23
tests/cases/compiler/defaultArgsInFunctionExpressions.ts(5,1): error TS2322: Type 'number' is not assignable to type 'string'.
34
tests/cases/compiler/defaultArgsInFunctionExpressions.ts(8,20): error TS2322: Type 'number' is not assignable to type 'string'.
@@ -8,11 +9,13 @@ tests/cases/compiler/defaultArgsInFunctionExpressions.ts(20,62): error TS2352: N
89
tests/cases/compiler/defaultArgsInFunctionExpressions.ts(28,15): error TS2304: Cannot find name 'T'.
910

1011

11-
==== tests/cases/compiler/defaultArgsInFunctionExpressions.ts (8 errors) ====
12+
==== tests/cases/compiler/defaultArgsInFunctionExpressions.ts (9 errors) ====
1213
var f = function (a = 3) { return a; }; // Type should be (a?: number) => number
1314
var n: number = f(4);
1415
n = f();
1516
var s: string = f('');
17+
~
18+
!!! error TS2322: Type 'number' is not assignable to type 'string'.
1619
~~
1720
!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
1821
s = f();

tests/baselines/reference/destructuringParameterProperties5.errors.txt

+17-2
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,14 @@ tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(1
1111
Types of property '0' are incompatible.
1212
Type '{ x1: number; x2: string; x3: boolean; }' is not assignable to type '{ x: number; y: string; z: boolean; }'.
1313
Object literal may only specify known properties, and 'x1' does not exist in type '{ x: number; y: string; z: boolean; }'.
14+
tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(12,39): error TS2339: Property 'x1' does not exist on type 'C1'.
15+
tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(12,45): error TS2339: Property 'x2' does not exist on type 'C1'.
16+
tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(12,51): error TS2339: Property 'x3' does not exist on type 'C1'.
17+
tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(12,57): error TS2339: Property 'y' does not exist on type 'C1'.
18+
tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(12,62): error TS2339: Property 'z' does not exist on type 'C1'.
1419

1520

16-
==== tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts (10 errors) ====
21+
==== tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts (15 errors) ====
1722
type ObjType1 = { x: number; y: string; z: boolean }
1823
type TupleType1 = [ObjType1, number, string]
1924

@@ -48,4 +53,14 @@ tests/cases/conformance/es6/destructuring/destructuringParameterProperties5.ts(1
4853
!!! error TS2345: Types of property '0' are incompatible.
4954
!!! error TS2345: Type '{ x1: number; x2: string; x3: boolean; }' is not assignable to type '{ x: number; y: string; z: boolean; }'.
5055
!!! error TS2345: Object literal may only specify known properties, and 'x1' does not exist in type '{ x: number; y: string; z: boolean; }'.
51-
var [a_x1, a_x2, a_x3, a_y, a_z] = [a.x1, a.x2, a.x3, a.y, a.z];
56+
var [a_x1, a_x2, a_x3, a_y, a_z] = [a.x1, a.x2, a.x3, a.y, a.z];
57+
~~
58+
!!! error TS2339: Property 'x1' does not exist on type 'C1'.
59+
~~
60+
!!! error TS2339: Property 'x2' does not exist on type 'C1'.
61+
~~
62+
!!! error TS2339: Property 'x3' does not exist on type 'C1'.
63+
~
64+
!!! error TS2339: Property 'y' does not exist on type 'C1'.
65+
~
66+
!!! error TS2339: Property 'z' does not exist on type 'C1'.

tests/baselines/reference/instantiateNonGenericTypeWithTypeArguments.errors.txt

+1-7
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiateNonGenericTypeWithTypeArguments.ts(8,9): error TS2346: Supplied parameters do not match any signature of call target.
22
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiateNonGenericTypeWithTypeArguments.ts(11,9): error TS2346: Supplied parameters do not match any signature of call target.
3-
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiateNonGenericTypeWithTypeArguments.ts(11,9): error TS2350: Only a void function can be called with the 'new' keyword.
43
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiateNonGenericTypeWithTypeArguments.ts(14,10): error TS2346: Supplied parameters do not match any signature of call target.
5-
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiateNonGenericTypeWithTypeArguments.ts(14,10): error TS2350: Only a void function can be called with the 'new' keyword.
64
tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiateNonGenericTypeWithTypeArguments.ts(18,10): error TS2347: Untyped function calls may not accept type arguments.
75

86

9-
==== tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiateNonGenericTypeWithTypeArguments.ts (6 errors) ====
7+
==== tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiateNonGenericTypeWithTypeArguments.ts (4 errors) ====
108
// it is an error to provide type arguments to a non-generic call
119
// all of these are errors
1210

@@ -22,15 +20,11 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiateNonGen
2220
var r = new Foo<number>();
2321
~~~~~~~~~~~~~~~~~
2422
!!! error TS2346: Supplied parameters do not match any signature of call target.
25-
~~~~~~~~~~~~~~~~~
26-
!!! error TS2350: Only a void function can be called with the 'new' keyword.
2723

2824
var f: { (): void };
2925
var r2 = new f<number>();
3026
~~~~~~~~~~~~~~~
3127
!!! error TS2346: Supplied parameters do not match any signature of call target.
32-
~~~~~~~~~~~~~~~
33-
!!! error TS2350: Only a void function can be called with the 'new' keyword.
3428

3529
var a: any;
3630
// BUG 790977

tests/baselines/reference/orderMattersForSignatureGroupIdentity.errors.txt

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
tests/cases/compiler/orderMattersForSignatureGroupIdentity.ts(19,5): error TS2345: Argument of type '{ s: string; n: number; }' is not assignable to parameter of type '{ n: number; }'.
22
Object literal may only specify known properties, and 's' does not exist in type '{ n: number; }'.
3+
tests/cases/compiler/orderMattersForSignatureGroupIdentity.ts(19,20): error TS2339: Property 'toLowerCase' does not exist on type 'number'.
34
tests/cases/compiler/orderMattersForSignatureGroupIdentity.ts(22,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'w' must be of type 'A', but here has type 'C'.
45
tests/cases/compiler/orderMattersForSignatureGroupIdentity.ts(24,5): error TS2345: Argument of type '{ s: string; n: number; }' is not assignable to parameter of type '{ n: number; }'.
56
Object literal may only specify known properties, and 's' does not exist in type '{ n: number; }'.
7+
tests/cases/compiler/orderMattersForSignatureGroupIdentity.ts(24,20): error TS2339: Property 'toLowerCase' does not exist on type 'number'.
68

79

8-
==== tests/cases/compiler/orderMattersForSignatureGroupIdentity.ts (3 errors) ====
10+
==== tests/cases/compiler/orderMattersForSignatureGroupIdentity.ts (5 errors) ====
911
interface A {
1012
(x: { s: string }): string
1113
(x: { n: number }): number
@@ -28,6 +30,8 @@ tests/cases/compiler/orderMattersForSignatureGroupIdentity.ts(24,5): error TS234
2830
~~~~~
2931
!!! error TS2345: Argument of type '{ s: string; n: number; }' is not assignable to parameter of type '{ n: number; }'.
3032
!!! error TS2345: Object literal may only specify known properties, and 's' does not exist in type '{ n: number; }'.
33+
~~~~~~~~~~~
34+
!!! error TS2339: Property 'toLowerCase' does not exist on type 'number'.
3135

3236
var w: A;
3337
var w: C;
@@ -37,4 +41,6 @@ tests/cases/compiler/orderMattersForSignatureGroupIdentity.ts(24,5): error TS234
3741
w({ s: "", n: 0 }).toLowerCase();
3842
~~~~~
3943
!!! error TS2345: Argument of type '{ s: string; n: number; }' is not assignable to parameter of type '{ n: number; }'.
40-
!!! error TS2345: Object literal may only specify known properties, and 's' does not exist in type '{ n: number; }'.
44+
!!! error TS2345: Object literal may only specify known properties, and 's' does not exist in type '{ n: number; }'.
45+
~~~~~~~~~~~
46+
!!! error TS2339: Property 'toLowerCase' does not exist on type 'number'.

tests/baselines/reference/overload1.errors.txt

+4-1
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ tests/cases/compiler/overload1.ts(29,1): error TS2322: Type 'number' is not assi
33
tests/cases/compiler/overload1.ts(31,3): error TS2346: Supplied parameters do not match any signature of call target.
44
tests/cases/compiler/overload1.ts(32,3): error TS2346: Supplied parameters do not match any signature of call target.
55
tests/cases/compiler/overload1.ts(33,1): error TS2322: Type 'C' is not assignable to type 'string'.
6+
tests/cases/compiler/overload1.ts(34,1): error TS2322: Type 'number' is not assignable to type 'string'.
67
tests/cases/compiler/overload1.ts(34,9): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'.
78

89

9-
==== tests/cases/compiler/overload1.ts (6 errors) ====
10+
==== tests/cases/compiler/overload1.ts (7 errors) ====
1011
module O {
1112
export class A {
1213

@@ -51,6 +52,8 @@ tests/cases/compiler/overload1.ts(34,9): error TS2345: Argument of type 'number'
5152
~
5253
!!! error TS2322: Type 'C' is not assignable to type 'string'.
5354
z=x.h(2,2); // no match
55+
~
56+
!!! error TS2322: Type 'number' is not assignable to type 'string'.
5457
~
5558
!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'.
5659
z=x.h("hello",0); // good

0 commit comments

Comments
 (0)