Skip to content

Commit 47bded0

Browse files
committed
Specify error message for type argument inference failing
1 parent e8d5fdc commit 47bded0

File tree

32 files changed

+135
-125
lines changed

32 files changed

+135
-125
lines changed

src/compiler/checker.ts

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ module ts {
129129
var emptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
130130
var anyFunctionType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
131131
var noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
132+
var typeArgumentInferenceFailureType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined);
132133

133134
var anySignature = createSignature(undefined, undefined, emptyArray, anyType, 0, false, false);
134135
var unknownSignature = createSignature(undefined, undefined, emptyArray, unknownType, 0, false, false);
@@ -3993,23 +3994,26 @@ module ts {
39933994
}
39943995

39953996
function getInferredType(context: InferenceContext, index: number): Type {
3996-
var result = context.inferredTypes[index];
3997-
if (!result) {
3997+
var inferredType = context.inferredTypes[index];
3998+
if (!inferredType) {
39983999
var inferences = context.inferences[index];
39994000
if (inferences.length) {
40004001
// Infer widened union or supertype, or the undefined type for no common supertype
40014002
var unionOrSuperType = context.inferUnionTypes ? getUnionType(inferences) : getCommonSupertype(inferences);
4002-
var inferredType = unionOrSuperType ? getWidenedType(unionOrSuperType) : undefinedType;
4003+
inferredType = unionOrSuperType ? getWidenedType(unionOrSuperType) : typeArgumentInferenceFailureType;
40034004
}
40044005
else {
40054006
// Infer the empty object type when no inferences were made
40064007
inferredType = emptyObjectType;
40074008
}
4008-
var constraint = getConstraintOfTypeParameter(context.typeParameters[index]);
4009-
var result = constraint && !isTypeAssignableTo(inferredType, constraint) ? constraint : inferredType;
4010-
context.inferredTypes[index] = result;
4009+
4010+
if (inferredType !== typeArgumentInferenceFailureType) {
4011+
var constraint = getConstraintOfTypeParameter(context.typeParameters[index]);
4012+
inferredType = constraint && !isTypeAssignableTo(inferredType, constraint) ? constraint : inferredType;
4013+
}
4014+
context.inferredTypes[index] = inferredType;
40114015
}
4012-
return result;
4016+
return inferredType;
40134017
}
40144018

40154019
function getInferredTypes(context: InferenceContext): Type[] {
@@ -5094,7 +5098,7 @@ module ts {
50945098
}
50955099
var inferredTypes = getInferredTypes(context);
50965100
// Inference has failed if the undefined type is in list of inferences
5097-
return !contains(inferredTypes, undefinedType);
5101+
return !contains(inferredTypes, typeArgumentInferenceFailureType);
50985102
}
50995103

51005104
function checkTypeArguments(signature: Signature, typeArguments: TypeNode[], typeArgumentResultTypes: Type[], reportErrors: boolean): boolean {
@@ -5161,6 +5165,7 @@ module ts {
51615165

51625166
var candidateForArgumentError: Signature;
51635167
var candidateForTypeArgumentError: Signature;
5168+
var indexOfUninferredTypeParameter: number;
51645169
var result: Signature;
51655170
if (candidates.length > 1) {
51665171
result = chooseOverload(candidates, subtypeRelation, excludeArgument);
@@ -5169,6 +5174,7 @@ module ts {
51695174
// Reinitialize these pointers for round two
51705175
candidateForArgumentError = undefined;
51715176
candidateForTypeArgumentError = undefined;
5177+
indexOfUninferredTypeParameter = undefined;
51725178
result = chooseOverload(candidates, assignableRelation, excludeArgument);
51735179
}
51745180
if (result) {
@@ -5187,7 +5193,8 @@ module ts {
51875193
checkTypeArguments(candidateForTypeArgumentError, node.typeArguments, [], /*reportErrors*/ true)
51885194
}
51895195
else {
5190-
error(node.func, Diagnostics.The_type_arguments_cannot_be_inferred_from_the_usage_Try_specifying_the_type_arguments_explicitly);
5196+
error(node.func, Diagnostics.The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Try_specifying_the_type_arguments_explicitly,
5197+
typeToString(candidateForTypeArgumentError.typeParameters[indexOfUninferredTypeParameter]));
51915198
}
51925199
}
51935200
else {
@@ -5251,6 +5258,9 @@ module ts {
52515258
}
52525259
else {
52535260
candidateForTypeArgumentError = originalCandidate;
5261+
if (!node.typeArguments) {
5262+
indexOfUninferredTypeParameter = typeArgumentTypes.indexOf(typeArgumentInferenceFailureType);
5263+
}
52545264
}
52555265
}
52565266
else {

src/compiler/diagnosticInformationMap.generated.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ module ts {
261261
Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses: { code: 2445, category: DiagnosticCategory.Error, key: "Property '{0}' is protected and only accessible within class '{1}' and its subclasses." },
262262
Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1: { code: 2446, category: DiagnosticCategory.Error, key: "Property '{0}' is protected and only accessible through an instance of class '{1}'." },
263263
The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead: { code: 2447, category: DiagnosticCategory.Error, key: "The '{0}' operator is not allowed for boolean types. Consider using '{1}' instead." },
264-
The_type_arguments_cannot_be_inferred_from_the_usage_Try_specifying_the_type_arguments_explicitly: { code: 2448, category: DiagnosticCategory.Error, key: "The type arguments cannot be inferred from the usage. Try specifying the type arguments explicitly." },
264+
The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Try_specifying_the_type_arguments_explicitly: { code: 2448, category: DiagnosticCategory.Error, key: "The type argument for type parameter '{0}' cannot be inferred from the usage. Try specifying the type arguments explicitly." },
265265
Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." },
266266
Type_parameter_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: { code: 4001, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using name '{1}' from private module '{2}'." },
267267
Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." },

src/compiler/diagnosticMessages.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1036,7 +1036,7 @@
10361036
"category": "Error",
10371037
"code": 2447
10381038
},
1039-
"The type arguments cannot be inferred from the usage. Try specifying the type arguments explicitly.": {
1039+
"The type argument for type parameter '{0}' cannot be inferred from the usage. Try specifying the type arguments explicitly.": {
10401040
"category": "Error",
10411041
"code": 2448
10421042
},
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
tests/cases/compiler/contextualTypingWithFixedTypeParameters1.ts(2,22): error TS2339: Property 'foo' does not exist on type 'string'.
2-
tests/cases/compiler/contextualTypingWithFixedTypeParameters1.ts(3,10): error TS2448: The type arguments cannot be inferred from the usage. Try specifying the type arguments explicitly.
2+
tests/cases/compiler/contextualTypingWithFixedTypeParameters1.ts(3,10): error TS2448: The type argument for type parameter 'T' cannot be inferred from the usage. Try specifying the type arguments explicitly.
33

44

55
==== tests/cases/compiler/contextualTypingWithFixedTypeParameters1.ts (2 errors) ====
@@ -9,4 +9,4 @@ tests/cases/compiler/contextualTypingWithFixedTypeParameters1.ts(3,10): error TS
99
!!! error TS2339: Property 'foo' does not exist on type 'string'.
1010
var r9 = f10('', () => (a => a.foo), 1); // error
1111
~~~
12-
!!! error TS2448: The type arguments cannot be inferred from the usage. Try specifying the type arguments explicitly.
12+
!!! error TS2448: The type argument for type parameter 'T' cannot be inferred from the usage. Try specifying the type arguments explicitly.

tests/baselines/reference/defaultBestCommonTypesHaveDecls.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
tests/cases/compiler/defaultBestCommonTypesHaveDecls.ts(2,6): error TS2339: Property 'length' does not exist on type '{}'.
22
tests/cases/compiler/defaultBestCommonTypesHaveDecls.ts(5,6): error TS2339: Property 'length' does not exist on type 'Object'.
3-
tests/cases/compiler/defaultBestCommonTypesHaveDecls.ts(8,14): error TS2448: The type arguments cannot be inferred from the usage. Try specifying the type arguments explicitly.
3+
tests/cases/compiler/defaultBestCommonTypesHaveDecls.ts(8,14): error TS2448: The type argument for type parameter 'T' cannot be inferred from the usage. Try specifying the type arguments explicitly.
44

55

66
==== tests/cases/compiler/defaultBestCommonTypesHaveDecls.ts (3 errors) ====
@@ -17,7 +17,7 @@ tests/cases/compiler/defaultBestCommonTypesHaveDecls.ts(8,14): error TS2448: The
1717
function concat<T>(x: T, y: T): T { return null; }
1818
var result = concat(1, ""); // error
1919
~~~~~~
20-
!!! error TS2448: The type arguments cannot be inferred from the usage. Try specifying the type arguments explicitly.
20+
!!! error TS2448: The type argument for type parameter 'T' cannot be inferred from the usage. Try specifying the type arguments explicitly.
2121
var elementCount = result.length;
2222

2323
function concat2<T, U>(x: T, y: U) { return null; }
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
tests/cases/compiler/fixTypeParameterInSignatureWithRestParameters.ts(2,1): error TS2448: The type arguments cannot be inferred from the usage. Try specifying the type arguments explicitly.
1+
tests/cases/compiler/fixTypeParameterInSignatureWithRestParameters.ts(2,1): error TS2448: The type argument for type parameter 'T' cannot be inferred from the usage. Try specifying the type arguments explicitly.
22

33

44
==== tests/cases/compiler/fixTypeParameterInSignatureWithRestParameters.ts (1 errors) ====
55
function bar<T>(item1: T, item2: T) { }
66
bar(1, ""); // Should be ok
77
~~~
8-
!!! error TS2448: The type arguments cannot be inferred from the usage. Try specifying the type arguments explicitly.
8+
!!! error TS2448: The type argument for type parameter 'T' cannot be inferred from the usage. Try specifying the type arguments explicitly.

tests/baselines/reference/genericCallWithFunctionTypedArguments.errors.txt

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments.ts(26,10): error TS2448: The type arguments cannot be inferred from the usage. Try specifying the type arguments explicitly.
2-
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments.ts(30,15): error TS2448: The type arguments cannot be inferred from the usage. Try specifying the type arguments explicitly.
3-
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments.ts(33,15): error TS2448: The type arguments cannot be inferred from the usage. Try specifying the type arguments explicitly.
4-
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments.ts(34,16): error TS2448: The type arguments cannot be inferred from the usage. Try specifying the type arguments explicitly.
5-
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments.ts(35,15): error TS2448: The type arguments cannot be inferred from the usage. Try specifying the type arguments explicitly.
1+
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments.ts(26,10): error TS2448: The type argument for type parameter 'U' cannot be inferred from the usage. Try specifying the type arguments explicitly.
2+
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments.ts(30,15): error TS2448: The type argument for type parameter 'T' cannot be inferred from the usage. Try specifying the type arguments explicitly.
3+
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments.ts(33,15): error TS2448: The type argument for type parameter 'T' cannot be inferred from the usage. Try specifying the type arguments explicitly.
4+
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments.ts(34,16): error TS2448: The type argument for type parameter 'T' cannot be inferred from the usage. Try specifying the type arguments explicitly.
5+
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments.ts(35,15): error TS2448: The type argument for type parameter 'U' cannot be inferred from the usage. Try specifying the type arguments explicitly.
66

77

88
==== tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments.ts (5 errors) ====
@@ -33,22 +33,22 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFun
3333

3434
var r8 = foo3(1, function (a) { return '' }, 1); // error
3535
~~~~
36-
!!! error TS2448: The type arguments cannot be inferred from the usage. Try specifying the type arguments explicitly.
36+
!!! error TS2448: The type argument for type parameter 'U' cannot be inferred from the usage. Try specifying the type arguments explicitly.
3737
var r9 = foo3<number, string>(1, (a) => '', ''); // string
3838

3939
function other<T, U>(t: T, u: U) {
4040
var r10 = foo2(1, (x: T) => ''); // error
4141
~~~~
42-
!!! error TS2448: The type arguments cannot be inferred from the usage. Try specifying the type arguments explicitly.
42+
!!! error TS2448: The type argument for type parameter 'T' cannot be inferred from the usage. Try specifying the type arguments explicitly.
4343
var r10 = foo2(1, (x) => ''); // string
4444

4545
var r11 = foo3(1, (x: T) => '', ''); // error
4646
~~~~
47-
!!! error TS2448: The type arguments cannot be inferred from the usage. Try specifying the type arguments explicitly.
47+
!!! error TS2448: The type argument for type parameter 'T' cannot be inferred from the usage. Try specifying the type arguments explicitly.
4848
var r11b = foo3(1, (x: T) => '', 1); // error
4949
~~~~
50-
!!! error TS2448: The type arguments cannot be inferred from the usage. Try specifying the type arguments explicitly.
50+
!!! error TS2448: The type argument for type parameter 'T' cannot be inferred from the usage. Try specifying the type arguments explicitly.
5151
var r12 = foo3(1, function (a) { return '' }, 1); // error
5252
~~~~
53-
!!! error TS2448: The type arguments cannot be inferred from the usage. Try specifying the type arguments explicitly.
53+
!!! error TS2448: The type argument for type parameter 'U' cannot be inferred from the usage. Try specifying the type arguments explicitly.
5454
}

tests/baselines/reference/genericCallWithFunctionTypedArguments2.errors.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments2.ts(29,10): error TS2448: The type arguments cannot be inferred from the usage. Try specifying the type arguments explicitly.
2-
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments2.ts(40,10): error TS2448: The type arguments cannot be inferred from the usage. Try specifying the type arguments explicitly.
1+
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments2.ts(29,10): error TS2448: The type argument for type parameter 'T' cannot be inferred from the usage. Try specifying the type arguments explicitly.
2+
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments2.ts(40,10): error TS2448: The type argument for type parameter 'T' cannot be inferred from the usage. Try specifying the type arguments explicitly.
33

44

55
==== tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFunctionTypedArguments2.ts (2 errors) ====
@@ -33,7 +33,7 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFun
3333

3434
var r4 = foo2(1, i2); // error
3535
~~~~
36-
!!! error TS2448: The type arguments cannot be inferred from the usage. Try specifying the type arguments explicitly.
36+
!!! error TS2448: The type argument for type parameter 'T' cannot be inferred from the usage. Try specifying the type arguments explicitly.
3737
var r4b = foo2(1, a); // any
3838
var r5 = foo2(1, i); // any
3939
var r6 = foo2<string, string>('', i2); // string
@@ -46,5 +46,5 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithFun
4646
var r7b = foo3(null, a, ''); // any
4747
var r8 = foo3(1, i2, 1); // error
4848
~~~~
49-
!!! error TS2448: The type arguments cannot be inferred from the usage. Try specifying the type arguments explicitly.
49+
!!! error TS2448: The type argument for type parameter 'T' cannot be inferred from the usage. Try specifying the type arguments explicitly.
5050
var r9 = foo3<string, string>('', i2, ''); // string

tests/baselines/reference/genericCallWithGenericSignatureArguments.errors.txt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGenericSignatureArguments.ts(18,10): error TS2346: Supplied parameters do not match any signature of call target.
2-
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGenericSignatureArguments.ts(19,10): error TS2346: Supplied parameters do not match any signature of call target.
1+
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGenericSignatureArguments.ts(18,10): error TS2448: The type argument for type parameter 'T' cannot be inferred from the usage. Try specifying the type arguments explicitly.
2+
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGenericSignatureArguments.ts(19,10): error TS2448: The type argument for type parameter 'T' cannot be inferred from the usage. Try specifying the type arguments explicitly.
33

44

55
==== tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGenericSignatureArguments.ts (2 errors) ====
@@ -21,11 +21,11 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGen
2121
var b: { x: number; z?: number; };
2222

2323
var r4 = foo((x: typeof a) => a, (x: typeof b) => b); // typeof a => typeof a
24-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25-
!!! error TS2346: Supplied parameters do not match any signature of call target.
24+
~~~
25+
!!! error TS2448: The type argument for type parameter 'T' cannot be inferred from the usage. Try specifying the type arguments explicitly.
2626
var r5 = foo((x: typeof b) => b, (x: typeof a) => a); // typeof b => typeof b
27-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
28-
!!! error TS2346: Supplied parameters do not match any signature of call target.
27+
~~~
28+
!!! error TS2448: The type argument for type parameter 'T' cannot be inferred from the usage. Try specifying the type arguments explicitly.
2929

3030
function other<T>(x: T) {
3131
var r6 = foo((a: T) => a, (b: T) => b); // T => T

0 commit comments

Comments
 (0)