Skip to content

Commit 2b9166b

Browse files
author
Andy
authored
Don't recommend to install '@types/foo' if that already exists (#24815)
* Don't recommend to install '@types/foo' if that already exists * Add different extra diagnostic text if the @types package exists * Update API (#24966)
1 parent e7b338e commit 2b9166b

8 files changed

+135
-5
lines changed

src/compiler/checker.ts

+12-4
Original file line numberDiff line numberDiff line change
@@ -2283,16 +2283,24 @@ namespace ts {
22832283
}
22842284

22852285
function errorOnImplicitAnyModule(isError: boolean, errorNode: Node, { packageId, resolvedFileName }: ResolvedModuleFull, moduleReference: string): void {
2286-
const errorInfo = packageId && chainDiagnosticMessages(
2287-
/*details*/ undefined,
2288-
Diagnostics.Try_npm_install_types_Slash_0_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_module_0,
2289-
getMangledNameForScopedPackage(packageId.name));
2286+
const errorInfo = packageId
2287+
? chainDiagnosticMessages(
2288+
/*details*/ undefined,
2289+
typesPackageExists(packageId.name)
2290+
? Diagnostics.If_the_0_package_actually_exposes_this_module_consider_sending_a_pull_request_to_amend_https_Colon_Slash_Slashgithub_com_SlashDefinitelyTyped_SlashDefinitelyTyped_Slashtree_Slashmaster_Slashtypes_Slash_0
2291+
: Diagnostics.Try_npm_install_types_Slash_0_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_module_0,
2292+
getMangledNameForScopedPackage(packageId.name))
2293+
: undefined;
22902294
errorOrSuggestion(isError, errorNode, chainDiagnosticMessages(
22912295
errorInfo,
22922296
Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type,
22932297
moduleReference,
22942298
resolvedFileName));
22952299
}
2300+
function typesPackageExists(packageName: string): boolean {
2301+
return host.getSourceFiles().some(sf => !!sf.resolvedModules && !!forEachEntry(sf.resolvedModules, r =>
2302+
r && r.packageId && r.packageId.name === getTypesPackageName(packageName)));
2303+
}
22962304

22972305
// An external module with an 'export =' declaration resolves to the target of the 'export =' declaration,
22982306
// and an external module with no 'export =' declaration resolves to the module itself.

src/compiler/diagnosticMessages.json

+5-1
Original file line numberDiff line numberDiff line change
@@ -3636,7 +3636,7 @@
36363636
"category": "Message",
36373637
"code": 6353
36383638
},
3639-
3639+
36403640
"Project '{0}' is up to date with .d.ts files from its dependencies": {
36413641
"category": "Message",
36423642
"code": 6354
@@ -3836,6 +3836,10 @@
38363836
"category": "Error",
38373837
"code": 7039
38383838
},
3839+
"If the '{0}' package actually exposes this module, consider sending a pull request to amend 'https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/{0}`": {
3840+
"category": "Error",
3841+
"code": 7040
3842+
},
38393843
"You cannot rename this element.": {
38403844
"category": "Error",
38413845
"code": 8000

tests/baselines/reference/api/tsserverlibrary.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -5752,6 +5752,7 @@ declare namespace ts {
57525752
Enables_emit_interoperability_between_CommonJS_and_ES_Modules_via_creation_of_namespace_objects_for_all_imports_Implies_allowSyntheticDefaultImports: DiagnosticMessage;
57535753
Type_originates_at_this_import_A_namespace_style_import_cannot_be_called_or_constructed_and_will_cause_a_failure_at_runtime_Consider_using_a_default_import_or_import_require_here_instead: DiagnosticMessage;
57545754
Mapped_object_type_implicitly_has_an_any_template_type: DiagnosticMessage;
5755+
If_the_0_package_actually_exposes_this_module_consider_sending_a_pull_request_to_amend_https_Colon_Slash_Slashgithub_com_SlashDefinitelyTyped_SlashDefinitelyTyped_Slashtree_Slashmaster_Slashtypes_Slash_0: DiagnosticMessage;
57555756
You_cannot_rename_this_element: DiagnosticMessage;
57565757
You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library: DiagnosticMessage;
57575758
import_can_only_be_used_in_a_ts_file: DiagnosticMessage;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/a.ts(2,25): error TS7016: Could not find a declaration file for module 'foo/sub'. '/node_modules/foo/sub.js' implicitly has an 'any' type.
2+
If the 'foo' package actually exposes this module, consider sending a pull request to amend 'https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/foo`
3+
/a.ts(3,25): error TS7016: Could not find a declaration file for module 'bar/sub'. '/node_modules/bar/sub.js' implicitly has an 'any' type.
4+
Try `npm install @types/bar` if it exists or add a new declaration (.d.ts) file containing `declare module 'bar';`
5+
6+
7+
==== /a.ts (2 errors) ====
8+
import * as foo from "foo";
9+
import * as fooSub from "foo/sub";
10+
~~~~~~~~~
11+
!!! error TS7016: Could not find a declaration file for module 'foo/sub'. '/node_modules/foo/sub.js' implicitly has an 'any' type.
12+
!!! error TS7016: If the 'foo' package actually exposes this module, consider sending a pull request to amend 'https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/foo`
13+
import * as barSub from "bar/sub";
14+
~~~~~~~~~
15+
!!! error TS7016: Could not find a declaration file for module 'bar/sub'. '/node_modules/bar/sub.js' implicitly has an 'any' type.
16+
!!! error TS7016: Try `npm install @types/bar` if it exists or add a new declaration (.d.ts) file containing `declare module 'bar';`
17+
18+
==== /node_modules/@types/foo/index.d.ts (0 errors) ====
19+
export const foo: number;
20+
21+
==== /node_modules/@types/foo/package.json (0 errors) ====
22+
{ "name": "@types/foo", "version": "1.2.3" }
23+
24+
==== /node_modules/foo/sub.js (0 errors) ====
25+
const x = 0;
26+
27+
==== /node_modules/foo/package.json (0 errors) ====
28+
{ "name": "foo", "version": "1.2.3" }
29+
30+
==== /node_modules/bar/sub.js (0 errors) ====
31+
const x = 0;
32+
33+
==== /node_modules/bar/package.json (0 errors) ====
34+
{ "name": "bar", "version": "1.2.3" }
35+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//// [tests/cases/conformance/moduleResolution/untypedModuleImport_noImplicitAny_typesForPackageExist.ts] ////
2+
3+
//// [index.d.ts]
4+
export const foo: number;
5+
6+
//// [package.json]
7+
{ "name": "@types/foo", "version": "1.2.3" }
8+
9+
//// [sub.js]
10+
const x = 0;
11+
12+
//// [package.json]
13+
{ "name": "foo", "version": "1.2.3" }
14+
15+
//// [sub.js]
16+
const x = 0;
17+
18+
//// [package.json]
19+
{ "name": "bar", "version": "1.2.3" }
20+
21+
//// [a.ts]
22+
import * as foo from "foo";
23+
import * as fooSub from "foo/sub";
24+
import * as barSub from "bar/sub";
25+
26+
27+
//// [a.js]
28+
"use strict";
29+
exports.__esModule = true;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
=== /a.ts ===
2+
import * as foo from "foo";
3+
>foo : Symbol(foo, Decl(a.ts, 0, 6))
4+
5+
import * as fooSub from "foo/sub";
6+
>fooSub : Symbol(fooSub, Decl(a.ts, 1, 6))
7+
8+
import * as barSub from "bar/sub";
9+
>barSub : Symbol(barSub, Decl(a.ts, 2, 6))
10+
11+
=== /node_modules/@types/foo/index.d.ts ===
12+
export const foo: number;
13+
>foo : Symbol(foo, Decl(index.d.ts, 0, 12))
14+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
=== /a.ts ===
2+
import * as foo from "foo";
3+
>foo : typeof foo
4+
5+
import * as fooSub from "foo/sub";
6+
>fooSub : any
7+
8+
import * as barSub from "bar/sub";
9+
>barSub : any
10+
11+
=== /node_modules/@types/foo/index.d.ts ===
12+
export const foo: number;
13+
>foo : number
14+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// @noImplicitReferences: true
2+
// @strict: true
3+
4+
// @Filename: /node_modules/@types/foo/index.d.ts
5+
export const foo: number;
6+
7+
// @Filename: /node_modules/@types/foo/package.json
8+
{ "name": "@types/foo", "version": "1.2.3" }
9+
10+
// @Filename: /node_modules/foo/sub.js
11+
const x = 0;
12+
13+
// @Filename: /node_modules/foo/package.json
14+
{ "name": "foo", "version": "1.2.3" }
15+
16+
// @Filename: /node_modules/bar/sub.js
17+
const x = 0;
18+
19+
// @Filename: /node_modules/bar/package.json
20+
{ "name": "bar", "version": "1.2.3" }
21+
22+
// @Filename: /a.ts
23+
import * as foo from "foo";
24+
import * as fooSub from "foo/sub";
25+
import * as barSub from "bar/sub";

0 commit comments

Comments
 (0)