Skip to content

Commit 6b2ea46

Browse files
committed
improve Diagnostics for accidentally calling type-assertion expressions
1 parent af8e44a commit 6b2ea46

7 files changed

+144
-0
lines changed

src/compiler/checker.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19655,6 +19655,13 @@ namespace ts {
1965519655
error(node, Diagnostics.Value_of_type_0_is_not_callable_Did_you_mean_to_include_new, typeToString(funcType));
1965619656
}
1965719657
else {
19658+
if (node.arguments.length === 1 && isTypeAssertion(first(node.arguments))) {
19659+
const text = getSourceFileOfNode(node).text;
19660+
const pos = skipTrivia(text, node.expression.end, /* stepAfterLineBreak */ true) - 1;
19661+
if (isLineBreak(text.charCodeAt(pos))) {
19662+
error(node.expression, Diagnostics.It_is_highly_likely_that_you_are_missing_a_semicolon);
19663+
}
19664+
}
1965819665
invocationError(node, apparentType, SignatureKind.Call);
1965919666
}
1966019667
return resolveErrorCall(node);

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2457,6 +2457,10 @@
24572457
"category": "Error",
24582458
"code": 2733
24592459
},
2460+
"It is highly likely that you are missing a semicolon.": {
2461+
"category": "Error",
2462+
"code": 2734
2463+
},
24602464

24612465
"Import declaration '{0}' is using private name '{1}'.": {
24622466
"category": "Error",
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
tests/cases/compiler/betterErrorForAccidentallyCallingTypeAssertionExpressions.ts(3,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures.
2+
tests/cases/compiler/betterErrorForAccidentallyCallingTypeAssertionExpressions.ts(5,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures.
3+
tests/cases/compiler/betterErrorForAccidentallyCallingTypeAssertionExpressions.ts(7,1): error TS2734: It is highly likely that you are missing a semicolon.
4+
tests/cases/compiler/betterErrorForAccidentallyCallingTypeAssertionExpressions.ts(7,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures.
5+
tests/cases/compiler/betterErrorForAccidentallyCallingTypeAssertionExpressions.ts(10,1): error TS2734: It is highly likely that you are missing a semicolon.
6+
tests/cases/compiler/betterErrorForAccidentallyCallingTypeAssertionExpressions.ts(10,1): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures.
7+
8+
9+
==== tests/cases/compiler/betterErrorForAccidentallyCallingTypeAssertionExpressions.ts (6 errors) ====
10+
declare function foo(): string;
11+
12+
foo()(1 as number).toString();
13+
~~~~~~~~~~~~~~~~~~
14+
!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures.
15+
16+
foo() (1 as number).toString();
17+
~~~~~~~~~~~~~~~~~~~~~
18+
!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures.
19+
20+
foo()
21+
~~~~~
22+
!!! error TS2734: It is highly likely that you are missing a semicolon.
23+
~~~~~
24+
(1 as number).toString();
25+
~~~~~~~~~~~~~
26+
!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures.
27+
28+
foo()
29+
~~~~~
30+
!!! error TS2734: It is highly likely that you are missing a semicolon.
31+
~~~~~~~~
32+
(1 as number).toString();
33+
~~~~~~~~~~~~~~~~~
34+
!!! error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'String' has no compatible call signatures.
35+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//// [betterErrorForAccidentallyCallingTypeAssertionExpressions.ts]
2+
declare function foo(): string;
3+
4+
foo()(1 as number).toString();
5+
6+
foo() (1 as number).toString();
7+
8+
foo()
9+
(1 as number).toString();
10+
11+
foo()
12+
(1 as number).toString();
13+
14+
15+
//// [betterErrorForAccidentallyCallingTypeAssertionExpressions.js]
16+
foo()(1).toString();
17+
foo()(1).toString();
18+
foo()(1).toString();
19+
foo()(1).toString();
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
=== tests/cases/compiler/betterErrorForAccidentallyCallingTypeAssertionExpressions.ts ===
2+
declare function foo(): string;
3+
>foo : Symbol(foo, Decl(betterErrorForAccidentallyCallingTypeAssertionExpressions.ts, 0, 0))
4+
5+
foo()(1 as number).toString();
6+
>foo : Symbol(foo, Decl(betterErrorForAccidentallyCallingTypeAssertionExpressions.ts, 0, 0))
7+
8+
foo() (1 as number).toString();
9+
>foo : Symbol(foo, Decl(betterErrorForAccidentallyCallingTypeAssertionExpressions.ts, 0, 0))
10+
11+
foo()
12+
>foo : Symbol(foo, Decl(betterErrorForAccidentallyCallingTypeAssertionExpressions.ts, 0, 0))
13+
14+
(1 as number).toString();
15+
16+
foo()
17+
>foo : Symbol(foo, Decl(betterErrorForAccidentallyCallingTypeAssertionExpressions.ts, 0, 0))
18+
19+
(1 as number).toString();
20+
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
=== tests/cases/compiler/betterErrorForAccidentallyCallingTypeAssertionExpressions.ts ===
2+
declare function foo(): string;
3+
>foo : () => string
4+
5+
foo()(1 as number).toString();
6+
>foo()(1 as number).toString() : any
7+
>foo()(1 as number).toString : any
8+
>foo()(1 as number) : any
9+
>foo() : string
10+
>foo : () => string
11+
>1 as number : number
12+
>1 : 1
13+
>toString : any
14+
15+
foo() (1 as number).toString();
16+
>foo() (1 as number).toString() : any
17+
>foo() (1 as number).toString : any
18+
>foo() (1 as number) : any
19+
>foo() : string
20+
>foo : () => string
21+
>1 as number : number
22+
>1 : 1
23+
>toString : any
24+
25+
foo()
26+
>foo()(1 as number).toString() : any
27+
>foo()(1 as number).toString : any
28+
>foo()(1 as number) : any
29+
>foo() : string
30+
>foo : () => string
31+
32+
(1 as number).toString();
33+
>1 as number : number
34+
>1 : 1
35+
>toString : any
36+
37+
foo()
38+
>foo() (1 as number).toString() : any
39+
>foo() (1 as number).toString : any
40+
>foo() (1 as number) : any
41+
>foo() : string
42+
>foo : () => string
43+
44+
(1 as number).toString();
45+
>1 as number : number
46+
>1 : 1
47+
>toString : any
48+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
declare function foo(): string;
2+
3+
foo()(1 as number).toString();
4+
5+
foo() (1 as number).toString();
6+
7+
foo()
8+
(1 as number).toString();
9+
10+
foo()
11+
(1 as number).toString();

0 commit comments

Comments
 (0)