From 45f35b948602f1ca05b28511187ae582fb586bbb Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Mon, 30 Jan 2023 22:00:04 +0200 Subject: [PATCH 1/4] fix(52514): report noImplicitAny errors on missing return types --- src/compiler/checker.ts | 11 +++++- .../jsFileMethodOverloads3.errors.txt | 30 ++++++++++++++++ .../reference/jsFileMethodOverloads3.symbols | 31 ++++++++++++++++ .../reference/jsFileMethodOverloads3.types | 35 +++++++++++++++++++ .../cases/compiler/jsFileMethodOverloads3.ts | 26 ++++++++++++++ 5 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/jsFileMethodOverloads3.errors.txt create mode 100644 tests/baselines/reference/jsFileMethodOverloads3.symbols create mode 100644 tests/baselines/reference/jsFileMethodOverloads3.types create mode 100644 tests/cases/compiler/jsFileMethodOverloads3.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ca37ad9acf807..a73c4f7cff646 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._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type, idText(declaration.parent.tagName), typeAsString); + } + return; case SyntaxKind.FunctionDeclaration: case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: diff --git a/tests/baselines/reference/jsFileMethodOverloads3.errors.txt b/tests/baselines/reference/jsFileMethodOverloads3.errors.txt new file mode 100644 index 0000000000000..9936455636d71 --- /dev/null +++ b/tests/baselines/reference/jsFileMethodOverloads3.errors.txt @@ -0,0 +1,30 @@ +/a.js(2,5): error TS7010: 'overload', which lacks return-type annotation, implicitly has an 'any' return type. +/a.js(7,5): error TS7010: 'overload', which lacks return-type annotation, implicitly has an 'any' return type. + + +==== /a.js (2 errors) ==== + /** + * @overload + ~~~~~~~~ +!!! error TS7010: 'overload', which lacks return-type annotation, implicitly has an 'any' return type. + * @param {number} x + */ + + /** + * @overload + ~~~~~~~~ +!!! error TS7010: 'overload', which lacks return-type annotation, implicitly has an 'any' return type. + * @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/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"); From 1e3b2bafd40e955e73050e4cad49c5f65b40a669 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Mon, 30 Jan 2023 23:30:40 +0200 Subject: [PATCH 2/4] update diagnostic message --- src/compiler/checker.ts | 5 ++++- src/compiler/diagnosticMessages.json | 4 ++++ .../reference/jsFileMethodOverloads3.errors.txt | 12 ++++++------ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a73c4f7cff646..75b81b81aabcf 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -23425,7 +23425,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return; case SyntaxKind.JSDocSignature: if (noImplicitAny && isJSDocOverloadTag(declaration.parent)) { - error(declaration.parent.tagName, Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type, idText(declaration.parent.tagName), typeAsString); + const jsDocOverloadTag = declaration.parent; + const sourceFile = getSourceFileOfNode(jsDocOverloadTag); + diagnostics.add( + createFileDiagnostic(sourceFile, jsDocOverloadTag.pos, jsDocOverloadTag.tagName.end - jsDocOverloadTag.pos, Diagnostics.This_overload_implicitly_returns_the_type_0_because_it_lacks_a_return_type_annotation, typeAsString)); } return; case SyntaxKind.FunctionDeclaration: 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 index 9936455636d71..60035f338e302 100644 --- a/tests/baselines/reference/jsFileMethodOverloads3.errors.txt +++ b/tests/baselines/reference/jsFileMethodOverloads3.errors.txt @@ -1,19 +1,19 @@ -/a.js(2,5): error TS7010: 'overload', which lacks return-type annotation, implicitly has an 'any' return type. -/a.js(7,5): error TS7010: 'overload', which lacks return-type annotation, implicitly has an 'any' return type. +/a.js(2,4): error TS7012: This overload implicitly returns the type 'any' because it lacks a return type annotation. +/a.js(7,4): error TS7012: This overload implicitly returns the type 'any' because it lacks a return type annotation. ==== /a.js (2 errors) ==== /** * @overload - ~~~~~~~~ -!!! error TS7010: 'overload', which lacks return-type annotation, implicitly has an 'any' return type. + ~~~~~~~~~ +!!! error TS7012: This overload implicitly returns the type 'any' because it lacks a return type annotation. * @param {number} x */ /** * @overload - ~~~~~~~~ -!!! error TS7010: 'overload', which lacks return-type annotation, implicitly has an 'any' return type. + ~~~~~~~~~ +!!! error TS7012: This overload implicitly returns the type 'any' because it lacks a return type annotation. * @param {string} x */ From c9560b76b02c11416c0410e7d21082ae8e07aac0 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Mon, 30 Jan 2023 23:47:56 +0200 Subject: [PATCH 3/4] update baseline --- .../tsserver/plugins/getSupportedCodeFixes-can-be-proxied.js | 3 +++ 1 file changed, 3 insertions(+) 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", From 16f0192003132ea6c25a6419f7a8f6f90c5f9dec Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Tue, 31 Jan 2023 19:13:45 +0200 Subject: [PATCH 4/4] update error node --- src/compiler/checker.ts | 5 +---- .../baselines/reference/jsFileMethodOverloads3.errors.txt | 8 ++++---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 75b81b81aabcf..68c7785d275db 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -23425,10 +23425,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return; case SyntaxKind.JSDocSignature: if (noImplicitAny && isJSDocOverloadTag(declaration.parent)) { - const jsDocOverloadTag = declaration.parent; - const sourceFile = getSourceFileOfNode(jsDocOverloadTag); - diagnostics.add( - createFileDiagnostic(sourceFile, jsDocOverloadTag.pos, jsDocOverloadTag.tagName.end - jsDocOverloadTag.pos, Diagnostics.This_overload_implicitly_returns_the_type_0_because_it_lacks_a_return_type_annotation, typeAsString)); + error(declaration.parent.tagName, Diagnostics.This_overload_implicitly_returns_the_type_0_because_it_lacks_a_return_type_annotation, typeAsString); } return; case SyntaxKind.FunctionDeclaration: diff --git a/tests/baselines/reference/jsFileMethodOverloads3.errors.txt b/tests/baselines/reference/jsFileMethodOverloads3.errors.txt index 60035f338e302..edc21e0e064d7 100644 --- a/tests/baselines/reference/jsFileMethodOverloads3.errors.txt +++ b/tests/baselines/reference/jsFileMethodOverloads3.errors.txt @@ -1,18 +1,18 @@ -/a.js(2,4): error TS7012: This overload implicitly returns the type 'any' because it lacks a return type annotation. -/a.js(7,4): error TS7012: This overload implicitly returns the type 'any' because it lacks a return type annotation. +/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 */