Skip to content

Commit 995f746

Browse files
author
Andy
authored
Add implicit-any error on JSDocFunctionType with no return type (#28487)
1 parent 11eee2b commit 995f746

7 files changed

+91
-7
lines changed

src/compiler/checker.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13534,6 +13534,9 @@ namespace ts {
1353413534
case SyntaxKind.BindingElement:
1353513535
diagnostic = Diagnostics.Binding_element_0_implicitly_has_an_1_type;
1353613536
break;
13537+
case SyntaxKind.JSDocFunctionType:
13538+
error(declaration, Diagnostics.Function_type_which_lacks_return_type_annotation_implicitly_has_an_0_return_type, typeAsString);
13539+
return;
1353713540
case SyntaxKind.FunctionDeclaration:
1353813541
case SyntaxKind.MethodDeclaration:
1353913542
case SyntaxKind.MethodSignature:
@@ -24401,6 +24404,13 @@ namespace ts {
2440124404
}
2440224405
}
2440324406

24407+
function checkJSDocFunctionType(node: JSDocFunctionType): void {
24408+
if (produceDiagnostics && !node.type && !isJSDocConstructSignature(node)) {
24409+
reportImplicitAny(node, anyType);
24410+
}
24411+
checkSignatureDeclaration(node);
24412+
}
24413+
2440424414
function checkJSDocAugmentsTag(node: JSDocAugmentsTag): void {
2440524415
const classLike = getJSDocHost(node);
2440624416
if (!isClassDeclaration(classLike) && !isClassExpression(classLike)) {
@@ -27404,7 +27414,7 @@ namespace ts {
2740427414
case SyntaxKind.JSDocParameterTag:
2740527415
return checkJSDocParameterTag(node as JSDocParameterTag);
2740627416
case SyntaxKind.JSDocFunctionType:
27407-
checkSignatureDeclaration(node as JSDocFunctionType);
27417+
checkJSDocFunctionType(node as JSDocFunctionType);
2740827418
// falls through
2740927419
case SyntaxKind.JSDocNonNullableType:
2741027420
case SyntaxKind.JSDocNullableType:

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3979,6 +3979,10 @@
39793979
"category": "Error",
39803980
"code": 7013
39813981
},
3982+
"Function type, which lacks return-type annotation, implicitly has an '{0}' return type.": {
3983+
"category": "Error",
3984+
"code": 7014
3985+
},
39823986
"Element implicitly has an 'any' type because index expression is not of type 'number'.": {
39833987
"category": "Error",
39843988
"code": 7015

src/compiler/utilities.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2091,10 +2091,9 @@ namespace ts {
20912091
}
20922092

20932093
export function isJSDocConstructSignature(node: Node) {
2094-
return node.kind === SyntaxKind.JSDocFunctionType &&
2095-
(node as JSDocFunctionType).parameters.length > 0 &&
2096-
(node as JSDocFunctionType).parameters[0].name &&
2097-
((node as JSDocFunctionType).parameters[0].name as Identifier).escapedText === "new";
2094+
const param = isJSDocFunctionType(node) ? firstOrUndefined(node.parameters) : undefined;
2095+
const name = tryCast(param && param.name, isIdentifier);
2096+
return !!name && name.escapedText === "new";
20982097
}
20992098

21002099
export function isJSDocTypeAlias(node: Node): node is JSDocTypedefTag | JSDocCallbackTag {
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
tests/cases/conformance/jsdoc/0.js(24,12): error TS7014: Function type, which lacks return-type annotation, implicitly has an 'any' return type.
2+
3+
4+
==== tests/cases/conformance/jsdoc/0.js (1 errors) ====
5+
// @ts-check
6+
/** @type {String} */
7+
var S = "hello world";
8+
9+
/** @type {number} */
10+
var n = 10;
11+
12+
/** @type {*} */
13+
var anyT = 2;
14+
anyT = "hello";
15+
16+
/** @type {?} */
17+
var anyT1 = 2;
18+
anyT1 = "hi";
19+
20+
/** @type {Function} */
21+
const x = (a) => a + 1;
22+
x(1);
23+
24+
/** @type {function} */
25+
const y = (a) => a + 1;
26+
y(1);
27+
28+
/** @type {function (number)} */
29+
~~~~~~~~~~~~~~~~~
30+
!!! error TS7014: Function type, which lacks return-type annotation, implicitly has an 'any' return type.
31+
const x1 = (a) => a + 1;
32+
x1(0);
33+
34+
/** @type {function (number): number} */
35+
const x2 = (a) => a + 1;
36+
x2(0);
37+
38+
/**
39+
* @type {object}
40+
*/
41+
var props = {};
42+
43+
/**
44+
* @type {Object}
45+
*/
46+
var props = {};
47+

tests/baselines/reference/checkJsdocTypeTag2.errors.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
tests/cases/conformance/jsdoc/0.js(3,5): error TS2322: Type 'true' is not assignable to type 'string'.
22
tests/cases/conformance/jsdoc/0.js(6,5): error TS2322: Type '"hello"' is not assignable to type 'number'.
3+
tests/cases/conformance/jsdoc/0.js(8,12): error TS7014: Function type, which lacks return-type annotation, implicitly has an 'any' return type.
34
tests/cases/conformance/jsdoc/0.js(10,4): error TS2345: Argument of type '"string"' is not assignable to parameter of type 'number'.
45
tests/cases/conformance/jsdoc/0.js(17,1): error TS2322: Type 'number' is not assignable to type 'string'.
56
tests/cases/conformance/jsdoc/0.js(20,21): error TS2339: Property 'concat' does not exist on type 'number'.
67
tests/cases/conformance/jsdoc/0.js(24,19): error TS2322: Type 'number' is not assignable to type 'string'.
78

89

9-
==== tests/cases/conformance/jsdoc/0.js (6 errors) ====
10+
==== tests/cases/conformance/jsdoc/0.js (7 errors) ====
1011
// @ts-check
1112
/** @type {String} */
1213
var S = true;
@@ -19,6 +20,8 @@ tests/cases/conformance/jsdoc/0.js(24,19): error TS2322: Type 'number' is not as
1920
!!! error TS2322: Type '"hello"' is not assignable to type 'number'.
2021

2122
/** @type {function (number)} */
23+
~~~~~~~~~~~~~~~~~
24+
!!! error TS7014: Function type, which lacks return-type annotation, implicitly has an 'any' return type.
2225
const x1 = (a) => a + 1;
2326
x1("string");
2427
~~~~~~~~

tests/baselines/reference/jsdocParameterParsingInfiniteLoop.errors.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1+
tests/cases/compiler/example.js(3,11): error TS7014: Function type, which lacks return-type annotation, implicitly has an 'any' return type.
12
tests/cases/compiler/example.js(3,20): error TS1110: Type expected.
23
tests/cases/compiler/example.js(3,21): error TS2304: Cannot find name 'foo'.
34

45

5-
==== tests/cases/compiler/example.js (2 errors) ====
6+
==== tests/cases/compiler/example.js (3 errors) ====
67
// @ts-check
78
/**
89
* @type {function(@foo)}
10+
~~~~~~~~~~~~~~
11+
!!! error TS7014: Function type, which lacks return-type annotation, implicitly has an 'any' return type.
912
~
1013
!!! error TS1110: Type expected.
1114
~~~
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
tests/cases/conformance/jsdoc/a.js(2,13): error TS7014: Function type, which lacks return-type annotation, implicitly has an 'any' return type.
2+
3+
4+
==== tests/cases/conformance/jsdoc/a.js (1 errors) ====
5+
// from bcryptjs
6+
/** @param {function(...[*])} callback */
7+
~~~~~~~~~~~~~~~~
8+
!!! error TS7014: Function type, which lacks return-type annotation, implicitly has an 'any' return type.
9+
function g(callback) {
10+
callback([1], [2], [3])
11+
}
12+
13+
/**
14+
* @type {!function(...number):string}
15+
* @inner
16+
*/
17+
var stringFromCharCode = String.fromCharCode;
18+

0 commit comments

Comments
 (0)