Skip to content

Commit da64479

Browse files
committed
Improve the error message when asserting to a type that is not
comparable to the original. Also improve the error message for implicit conversion of a symbol to a string in a template literal, which previously shared the error message with type assertions. Fixes microsoft#25539. Addresses microsoft#25870.
1 parent 7473772 commit da64479

27 files changed

+100
-95
lines changed

src/compiler/checker.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20041,7 +20041,8 @@ namespace ts {
2004120041
if (produceDiagnostics && targetType !== errorType) {
2004220042
const widenedType = getWidenedType(exprType);
2004320043
if (!isTypeComparableTo(targetType, widenedType)) {
20044-
checkTypeComparableTo(exprType, targetType, errNode, Diagnostics.Type_0_cannot_be_converted_to_type_1);
20044+
checkTypeComparableTo(exprType, targetType, errNode,
20045+
Diagnostics.Conversion_of_type_0_to_type_1_may_be_a_mistake_because_neither_type_sufficiently_overlaps_with_the_other_If_this_was_intentional_convert_the_expression_to_unknown_first);
2004520046
}
2004620047
}
2004720048
return targetType;
@@ -21515,7 +21516,7 @@ namespace ts {
2151521516
// in tagged templates.
2151621517
forEach(node.templateSpans, templateSpan => {
2151721518
if (maybeTypeOfKind(checkExpression(templateSpan.expression), TypeFlags.ESSymbolLike)) {
21518-
error(templateSpan.expression, Diagnostics.Type_0_cannot_be_converted_to_type_1, typeToString(esSymbolType), typeToString(stringType));
21519+
error(templateSpan.expression, Diagnostics.Implicit_conversion_of_a_symbol_to_a_string_will_fail_at_runtime_Consider_wrapping_this_expression_in_String);
2151921520
}
2152021521
});
2152121522

src/compiler/diagnosticMessages.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1196,7 +1196,7 @@
11961196
"category": "Error",
11971197
"code": 2351
11981198
},
1199-
"Type '{0}' cannot be converted to type '{1}'.": {
1199+
"Conversion of type '{0}' to type '{1}' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.": {
12001200
"category": "Error",
12011201
"code": 2352
12021202
},
@@ -2421,6 +2421,10 @@
24212421
"category": "Error",
24222422
"code": 2730
24232423
},
2424+
"Implicit conversion of a 'symbol' to a 'string' will fail at runtime. Consider wrapping this expression in 'String(...)'.": {
2425+
"category": "Error",
2426+
"code": 2731
2427+
},
24242428

24252429
"Import declaration '{0}' is using private name '{1}'.": {
24262430
"category": "Error",

tests/baselines/reference/arrayCast.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
tests/cases/compiler/arrayCast.ts(3,23): error TS2352: Type '{ foo: string; }[]' cannot be converted to type '{ id: number; }[]'.
1+
tests/cases/compiler/arrayCast.ts(3,23): error TS2352: Conversion of type '{ foo: string; }[]' to type '{ id: number; }[]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
22
Type '{ foo: string; }' is not comparable to type '{ id: number; }'.
33
Object literal may only specify known properties, and 'foo' does not exist in type '{ id: number; }'.
44

@@ -8,7 +8,7 @@ tests/cases/compiler/arrayCast.ts(3,23): error TS2352: Type '{ foo: string; }[]'
88
// has type { foo: string }[], which is not assignable to { id: number }[].
99
<{ id: number; }[]>[{ foo: "s" }];
1010
~~~~~~~~
11-
!!! error TS2352: Type '{ foo: string; }[]' cannot be converted to type '{ id: number; }[]'.
11+
!!! error TS2352: Conversion of type '{ foo: string; }[]' to type '{ id: number; }[]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
1212
!!! error TS2352: Type '{ foo: string; }' is not comparable to type '{ id: number; }'.
1313
!!! error TS2352: Object literal may only specify known properties, and 'foo' does not exist in type '{ id: number; }'.
1414

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
tests/cases/conformance/expressions/asOperator/asOperator2.ts(1,9): error TS2352: Type 'number' cannot be converted to type 'string'.
1+
tests/cases/conformance/expressions/asOperator/asOperator2.ts(1,9): error TS2352: Conversion of type 'number' to type 'string' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
22

33

44
==== tests/cases/conformance/expressions/asOperator/asOperator2.ts (1 errors) ====
55
var x = 23 as string;
66
~~~~~~~~~~~~
7-
!!! error TS2352: Type 'number' cannot be converted to type 'string'.
7+
!!! error TS2352: Conversion of type 'number' to type 'string' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
88

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
tests/cases/conformance/expressions/asOperator/asOperatorContextualType.ts(2,9): error TS2352: Type '(v: number) => number' cannot be converted to type '(x: number) => string'.
1+
tests/cases/conformance/expressions/asOperator/asOperatorContextualType.ts(2,9): error TS2352: Conversion of type '(v: number) => number' to type '(x: number) => string' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
22
Type 'number' is not comparable to type 'string'.
33

44

55
==== tests/cases/conformance/expressions/asOperator/asOperatorContextualType.ts (1 errors) ====
66
// should error
77
var x = (v => v) as (x: number) => string;
88
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9-
!!! error TS2352: Type '(v: number) => number' cannot be converted to type '(x: number) => string'.
9+
!!! error TS2352: Conversion of type '(v: number) => number' to type '(x: number) => string' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
1010
!!! error TS2352: Type 'number' is not comparable to type 'string'.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
tests/cases/conformance/expressions/asOperator/asOperatorNames.ts(2,9): error TS2352: Type 'number' cannot be converted to type 'string'.
1+
tests/cases/conformance/expressions/asOperator/asOperatorNames.ts(2,9): error TS2352: Conversion of type 'number' to type 'string' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
22

33

44
==== tests/cases/conformance/expressions/asOperator/asOperatorNames.ts (1 errors) ====
55
var a = 20;
66
var b = a as string;
77
~~~~~~~~~~~
8-
!!! error TS2352: Type 'number' cannot be converted to type 'string'.
8+
!!! error TS2352: Conversion of type 'number' to type 'string' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
99
var as = "hello";
1010
var as1 = as as string;
1111

tests/baselines/reference/castingTuple.errors.txt

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
tests/cases/conformance/types/tuple/castingTuple.ts(13,23): error TS2352: Type '[number, string]' cannot be converted to type '[number, string, boolean]'.
1+
tests/cases/conformance/types/tuple/castingTuple.ts(13,23): error TS2352: Conversion of type '[number, string]' to type '[number, string, boolean]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
22
Property '2' is missing in type '[number, string]'.
3-
tests/cases/conformance/types/tuple/castingTuple.ts(14,15): error TS2352: Type '[number, string, boolean]' cannot be converted to type '[number, string]'.
3+
tests/cases/conformance/types/tuple/castingTuple.ts(14,15): error TS2352: Conversion of type '[number, string, boolean]' to type '[number, string]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
44
Types of property 'length' are incompatible.
55
Type '3' is not comparable to type '2'.
6-
tests/cases/conformance/types/tuple/castingTuple.ts(15,14): error TS2352: Type '[number, string]' cannot be converted to type '[number, string, boolean]'.
7-
tests/cases/conformance/types/tuple/castingTuple.ts(18,21): error TS2352: Type '[C, D]' cannot be converted to type '[C, D, A]'.
6+
tests/cases/conformance/types/tuple/castingTuple.ts(15,14): error TS2352: Conversion of type '[number, string]' to type '[number, string, boolean]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
7+
tests/cases/conformance/types/tuple/castingTuple.ts(18,21): error TS2352: Conversion of type '[C, D]' to type '[C, D, A]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
88
Property '2' is missing in type '[C, D]'.
9-
tests/cases/conformance/types/tuple/castingTuple.ts(30,10): error TS2352: Type '[number, string]' cannot be converted to type '[number, number]'.
9+
tests/cases/conformance/types/tuple/castingTuple.ts(30,10): error TS2352: Conversion of type '[number, string]' to type '[number, number]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
1010
Type 'string' is not comparable to type 'number'.
11-
tests/cases/conformance/types/tuple/castingTuple.ts(31,10): error TS2352: Type '[C, D]' cannot be converted to type '[A, I]'.
11+
tests/cases/conformance/types/tuple/castingTuple.ts(31,10): error TS2352: Conversion of type '[C, D]' to type '[A, I]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
1212
Type 'C' is not comparable to type 'A'.
1313
Property 'a' is missing in type 'C'.
1414
tests/cases/conformance/types/tuple/castingTuple.ts(32,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'array1' must be of type '{}[]', but here has type 'number[]'.
@@ -30,21 +30,21 @@ tests/cases/conformance/types/tuple/castingTuple.ts(33,1): error TS2304: Cannot
3030
var emptyObjTuple = <[{}, {}]>numStrTuple;
3131
var numStrBoolTuple = <[number, string, boolean]>numStrTuple;
3232
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
33-
!!! error TS2352: Type '[number, string]' cannot be converted to type '[number, string, boolean]'.
33+
!!! error TS2352: Conversion of type '[number, string]' to type '[number, string, boolean]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
3434
!!! error TS2352: Property '2' is missing in type '[number, string]'.
3535
var shorter = numStrBoolTuple as [number, string]
3636
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
37-
!!! error TS2352: Type '[number, string, boolean]' cannot be converted to type '[number, string]'.
37+
!!! error TS2352: Conversion of type '[number, string, boolean]' to type '[number, string]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
3838
!!! error TS2352: Types of property 'length' are incompatible.
3939
!!! error TS2352: Type '3' is not comparable to type '2'.
4040
var longer = numStrTuple as [number, string, boolean]
4141
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
42-
!!! error TS2352: Type '[number, string]' cannot be converted to type '[number, string, boolean]'.
42+
!!! error TS2352: Conversion of type '[number, string]' to type '[number, string, boolean]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
4343
var classCDTuple: [C, D] = [new C(), new D()];
4444
var interfaceIITuple = <[I, I]>classCDTuple;
4545
var classCDATuple = <[C, D, A]>classCDTuple;
4646
~~~~~~~~~~~~~~~~~~~~~~~
47-
!!! error TS2352: Type '[C, D]' cannot be converted to type '[C, D, A]'.
47+
!!! error TS2352: Conversion of type '[C, D]' to type '[C, D, A]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
4848
!!! error TS2352: Property '2' is missing in type '[C, D]'.
4949
var eleFromCDA1 = classCDATuple[2]; // A
5050
var eleFromCDA2 = classCDATuple[5]; // C | D | A
@@ -59,11 +59,11 @@ tests/cases/conformance/types/tuple/castingTuple.ts(33,1): error TS2304: Cannot
5959
// error
6060
var t3 = <[number, number]>numStrTuple;
6161
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
62-
!!! error TS2352: Type '[number, string]' cannot be converted to type '[number, number]'.
62+
!!! error TS2352: Conversion of type '[number, string]' to type '[number, number]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
6363
!!! error TS2352: Type 'string' is not comparable to type 'number'.
6464
var t9 = <[A, I]>classCDTuple;
6565
~~~~~~~~~~~~~~~~~~~~
66-
!!! error TS2352: Type '[C, D]' cannot be converted to type '[A, I]'.
66+
!!! error TS2352: Conversion of type '[C, D]' to type '[A, I]' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
6767
!!! error TS2352: Type 'C' is not comparable to type 'A'.
6868
!!! error TS2352: Property 'a' is missing in type 'C'.
6969
var array1 = <number[]>numStrTuple;
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
tests/cases/compiler/contextualTyping39.ts(1,11): error TS2352: Type '() => string' cannot be converted to type '() => number'.
1+
tests/cases/compiler/contextualTyping39.ts(1,11): error TS2352: Conversion of type '() => string' to type '() => number' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
22
Type 'string' is not comparable to type 'number'.
33

44

55
==== tests/cases/compiler/contextualTyping39.ts (1 errors) ====
66
var foo = <{ (): number; }> function() { return "err"; };
77
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8-
!!! error TS2352: Type '() => string' cannot be converted to type '() => number'.
8+
!!! error TS2352: Conversion of type '() => string' to type '() => number' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
99
!!! error TS2352: Type 'string' is not comparable to type 'number'.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
tests/cases/compiler/contextualTyping41.ts(1,11): error TS2352: Type '() => string' cannot be converted to type '{ (): number; (i: number): number; }'.
1+
tests/cases/compiler/contextualTyping41.ts(1,11): error TS2352: Conversion of type '() => string' to type '{ (): number; (i: number): number; }' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
22
Type 'string' is not comparable to type 'number'.
33

44

55
==== tests/cases/compiler/contextualTyping41.ts (1 errors) ====
66
var foo = <{():number; (i:number):number; }> (function(){return "err";});
77
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8-
!!! error TS2352: Type '() => string' cannot be converted to type '{ (): number; (i: number): number; }'.
8+
!!! error TS2352: Conversion of type '() => string' to type '{ (): number; (i: number): number; }' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
99
!!! error TS2352: Type 'string' is not comparable to type 'number'.

tests/baselines/reference/defaultArgsInFunctionExpressions.errors.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ tests/cases/compiler/defaultArgsInFunctionExpressions.ts(4,19): error TS2345: Ar
22
tests/cases/compiler/defaultArgsInFunctionExpressions.ts(5,1): error TS2322: Type 'number' is not assignable to type 'string'.
33
tests/cases/compiler/defaultArgsInFunctionExpressions.ts(8,20): error TS2322: Type '3' is not assignable to type 'string'.
44
tests/cases/compiler/defaultArgsInFunctionExpressions.ts(11,1): error TS2322: Type 'string' is not assignable to type 'number'.
5-
tests/cases/compiler/defaultArgsInFunctionExpressions.ts(14,51): error TS2352: Type 'string' cannot be converted to type 'number'.
5+
tests/cases/compiler/defaultArgsInFunctionExpressions.ts(14,51): error TS2352: Conversion of type 'string' to type 'number' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
66
tests/cases/compiler/defaultArgsInFunctionExpressions.ts(17,41): error TS2322: Type '""' is not assignable to type 'number'.
7-
tests/cases/compiler/defaultArgsInFunctionExpressions.ts(20,62): error TS2352: Type 'string' cannot be converted to type 'number'.
7+
tests/cases/compiler/defaultArgsInFunctionExpressions.ts(20,62): error TS2352: Conversion of type 'string' to type 'number' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
88
tests/cases/compiler/defaultArgsInFunctionExpressions.ts(28,15): error TS2708: Cannot use namespace 'T' as a value.
99

1010

@@ -32,7 +32,7 @@ tests/cases/compiler/defaultArgsInFunctionExpressions.ts(28,15): error TS2708: C
3232
// Contextually type the default arg with the type annotation
3333
var f3 = function (a: (s: string) => any = (s) => <number>s) { };
3434
~~~~~~~~~
35-
!!! error TS2352: Type 'string' cannot be converted to type 'number'.
35+
!!! error TS2352: Conversion of type 'string' to type 'number' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
3636

3737
// Type check using the function's contextual type
3838
var f4: (a: number) => void = function (a = "") { };
@@ -42,7 +42,7 @@ tests/cases/compiler/defaultArgsInFunctionExpressions.ts(28,15): error TS2708: C
4242
// Contextually type the default arg using the function's contextual type
4343
var f5: (a: (s: string) => any) => void = function (a = s => <number>s) { };
4444
~~~~~~~~~
45-
!!! error TS2352: Type 'string' cannot be converted to type 'number'.
45+
!!! error TS2352: Conversion of type 'string' to type 'number' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
4646

4747
// Instantiated module
4848
module T { }

tests/baselines/reference/fuzzy.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ tests/cases/compiler/fuzzy.ts(13,18): error TS2420: Class 'C' incorrectly implem
22
Property 'alsoWorks' is missing in type 'C'.
33
tests/cases/compiler/fuzzy.ts(21,34): error TS2322: Type 'this' is not assignable to type 'I'.
44
Type 'C' is not assignable to type 'I'.
5-
tests/cases/compiler/fuzzy.ts(25,20): error TS2352: Type '{ oneI: this; }' cannot be converted to type 'R'.
5+
tests/cases/compiler/fuzzy.ts(25,20): error TS2352: Conversion of type '{ oneI: this; }' to type 'R' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
66
Property 'anything' is missing in type '{ oneI: this; }'.
77

88

@@ -40,7 +40,7 @@ tests/cases/compiler/fuzzy.ts(25,20): error TS2352: Type '{ oneI: this; }' canno
4040
worksToo():R {
4141
return <R>({ oneI: this });
4242
~~~~~~~~~~~~~~~~~~~
43-
!!! error TS2352: Type '{ oneI: this; }' cannot be converted to type 'R'.
43+
!!! error TS2352: Conversion of type '{ oneI: this; }' to type 'R' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
4444
!!! error TS2352: Property 'anything' is missing in type '{ oneI: this; }'.
4545
}
4646
}

0 commit comments

Comments
 (0)