diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ca37ad9acf807..68c7785d275db 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14446,7 +14446,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (node.tags) { for (const tag of node.tags) { if (isJSDocOverloadTag(tag)) { - result.push(getSignatureFromDeclaration(tag.typeExpression)); + const jsDocSignature = tag.typeExpression; + if (jsDocSignature.type === undefined) { + reportImplicitAny(jsDocSignature, anyType); + } + result.push(getSignatureFromDeclaration(jsDocSignature)); hasJSDocOverloads = true; } } @@ -23419,6 +23423,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { case SyntaxKind.JSDocFunctionType: error(declaration, Diagnostics.Function_type_which_lacks_return_type_annotation_implicitly_has_an_0_return_type, typeAsString); return; + case SyntaxKind.JSDocSignature: + if (noImplicitAny && isJSDocOverloadTag(declaration.parent)) { + error(declaration.parent.tagName, Diagnostics.This_overload_implicitly_returns_the_type_0_because_it_lacks_a_return_type_annotation, typeAsString); + } + return; case SyntaxKind.FunctionDeclaration: case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 866997b79bcfb..a566b30383fd1 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -6213,6 +6213,10 @@ "category": "Error", "code": 7011 }, + "This overload implicitly returns the type '{0}' because it lacks a return type annotation.": { + "category": "Error", + "code": 7012 + }, "Construct signature, which lacks return-type annotation, implicitly has an 'any' return type.": { "category": "Error", "code": 7013 diff --git a/tests/baselines/reference/jsFileMethodOverloads3.errors.txt b/tests/baselines/reference/jsFileMethodOverloads3.errors.txt new file mode 100644 index 0000000000000..edc21e0e064d7 --- /dev/null +++ b/tests/baselines/reference/jsFileMethodOverloads3.errors.txt @@ -0,0 +1,30 @@ +/a.js(2,5): error TS7012: This overload implicitly returns the type 'any' because it lacks a return type annotation. +/a.js(7,5): error TS7012: This overload implicitly returns the type 'any' because it lacks a return type annotation. + + +==== /a.js (2 errors) ==== + /** + * @overload + ~~~~~~~~ +!!! error TS7012: This overload implicitly returns the type 'any' because it lacks a return type annotation. + * @param {number} x + */ + + /** + * @overload + ~~~~~~~~ +!!! error TS7012: This overload implicitly returns the type 'any' because it lacks a return type annotation. + * @param {string} x + */ + + /** + * @param {string | number} x + * @returns {string | number} + */ + function id(x) { + return x; + } + + export let a = id(123); + export let b = id("hello"); + \ No newline at end of file diff --git a/tests/baselines/reference/jsFileMethodOverloads3.symbols b/tests/baselines/reference/jsFileMethodOverloads3.symbols new file mode 100644 index 0000000000000..3c01df14d64d8 --- /dev/null +++ b/tests/baselines/reference/jsFileMethodOverloads3.symbols @@ -0,0 +1,31 @@ +=== /a.js === +/** + * @overload + * @param {number} x + */ + +/** + * @overload + * @param {string} x + */ + +/** + * @param {string | number} x + * @returns {string | number} + */ +function id(x) { +>id : Symbol(id, Decl(a.js, 0, 0)) +>x : Symbol(x, Decl(a.js, 14, 12)) + + return x; +>x : Symbol(x, Decl(a.js, 14, 12)) +} + +export let a = id(123); +>a : Symbol(a, Decl(a.js, 18, 10)) +>id : Symbol(id, Decl(a.js, 0, 0)) + +export let b = id("hello"); +>b : Symbol(b, Decl(a.js, 19, 10)) +>id : Symbol(id, Decl(a.js, 0, 0)) + diff --git a/tests/baselines/reference/jsFileMethodOverloads3.types b/tests/baselines/reference/jsFileMethodOverloads3.types new file mode 100644 index 0000000000000..becfbed92323a --- /dev/null +++ b/tests/baselines/reference/jsFileMethodOverloads3.types @@ -0,0 +1,35 @@ +=== /a.js === +/** + * @overload + * @param {number} x + */ + +/** + * @overload + * @param {string} x + */ + +/** + * @param {string | number} x + * @returns {string | number} + */ +function id(x) { +>id : { (x: number): any; (x: string): any; } +>x : string | number + + return x; +>x : string | number +} + +export let a = id(123); +>a : any +>id(123) : any +>id : { (x: number): any; (x: string): any; } +>123 : 123 + +export let b = id("hello"); +>b : any +>id("hello") : any +>id : { (x: number): any; (x: string): any; } +>"hello" : "hello" + diff --git a/tests/baselines/reference/tsserver/plugins/getSupportedCodeFixes-can-be-proxied.js b/tests/baselines/reference/tsserver/plugins/getSupportedCodeFixes-can-be-proxied.js index 5a82b7befb823..9a2640baa418d 100644 --- a/tests/baselines/reference/tsserver/plugins/getSupportedCodeFixes-can-be-proxied.js +++ b/tests/baselines/reference/tsserver/plugins/getSupportedCodeFixes-can-be-proxied.js @@ -1363,6 +1363,7 @@ Info 32 [00:01:13.000] response: "6931", "7009", "7011", + "7012", "7013", "7014", "7015", @@ -2711,6 +2712,7 @@ Info 38 [00:01:19.000] response: "6931", "7009", "7011", + "7012", "7013", "7014", "7015", @@ -3971,6 +3973,7 @@ Info 40 [00:01:21.000] response: "6931", "7009", "7011", + "7012", "7013", "7014", "7015", diff --git a/tests/cases/compiler/jsFileMethodOverloads3.ts b/tests/cases/compiler/jsFileMethodOverloads3.ts new file mode 100644 index 0000000000000..5b089a3c23397 --- /dev/null +++ b/tests/cases/compiler/jsFileMethodOverloads3.ts @@ -0,0 +1,26 @@ +// @noImplicitAny: true +// @allowJs: true +// @checkJs: true +// @noEmit: true +// @filename: /a.js + +/** + * @overload + * @param {number} x + */ + +/** + * @overload + * @param {string} x + */ + +/** + * @param {string | number} x + * @returns {string | number} + */ +function id(x) { + return x; +} + +export let a = id(123); +export let b = id("hello");