diff --git a/src/services/codefixes/fixCannotFindModule.ts b/src/services/codefixes/fixCannotFindModule.ts index 9699cd3ceb4b5..fec421171d077 100644 --- a/src/services/codefixes/fixCannotFindModule.ts +++ b/src/services/codefixes/fixCannotFindModule.ts @@ -1,18 +1,22 @@ /* @internal */ namespace ts.codefix { const fixId = "fixCannotFindModule"; - const errorCodes = [Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type.code]; + const errorCodeCannotFindModule = Diagnostics.Cannot_find_module_0.code; + const errorCodes = [ + errorCodeCannotFindModule, + Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type.code, + ]; registerCodeFix({ errorCodes, getCodeActions: context => { const { host, sourceFile, span: { start } } = context; - const packageName = getTypesPackageNameToInstall(host, sourceFile, start); + const packageName = getTypesPackageNameToInstall(host, sourceFile, start, context.errorCode); return packageName === undefined ? [] : [createCodeFixAction(fixId, /*changes*/ [], [Diagnostics.Install_0, packageName], fixId, Diagnostics.Install_all_missing_types_packages, getCommand(sourceFile.fileName, packageName))]; }, fixIds: [fixId], getAllCodeActions: context => codeFixAll(context, errorCodes, (_, diag, commands) => { - const pkg = getTypesPackageNameToInstall(context.host, diag.file, diag.start); + const pkg = getTypesPackageNameToInstall(context.host, diag.file, diag.start, diag.code); if (pkg) { commands.push(getCommand(diag.file.fileName, pkg)); } @@ -23,9 +27,11 @@ namespace ts.codefix { return { type: "install package", file: fileName, packageName }; } - function getTypesPackageNameToInstall(host: LanguageServiceHost, sourceFile: SourceFile, pos: number): string | undefined { + function getTypesPackageNameToInstall(host: LanguageServiceHost, sourceFile: SourceFile, pos: number, diagCode: number): string | undefined { const moduleName = cast(getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false), isStringLiteral).text; const { packageName } = getPackageName(moduleName); - return host.isKnownTypesPackageName(packageName) ? getTypesPackageName(packageName) : undefined; + return diagCode === errorCodeCannotFindModule + ? (JsTyping.nodeCoreModules.has(packageName) ? "@types/node" : undefined) + : (host.isKnownTypesPackageName(packageName) ? getTypesPackageName(packageName) : undefined); } } diff --git a/src/services/jsTyping.ts b/src/services/jsTyping.ts index 6b4f7f2e1d4ea..907003b7db762 100644 --- a/src/services/jsTyping.ts +++ b/src/services/jsTyping.ts @@ -39,7 +39,8 @@ namespace ts.JsTyping { "crypto", "stream", "util", "assert", "tty", "domain", "constants", "process", "v8", "timers", "console"]; - const nodeCoreModules = arrayToSet(nodeCoreModuleList); + /* @internal */ + export const nodeCoreModules = arrayToSet(nodeCoreModuleList); /** * A map of loose file names to library names that we are confident require typings diff --git a/tests/cases/fourslash/codeFixCannotFindModule_nodeCoreModules.ts b/tests/cases/fourslash/codeFixCannotFindModule_nodeCoreModules.ts new file mode 100644 index 0000000000000..7e2af409bb0ab --- /dev/null +++ b/tests/cases/fourslash/codeFixCannotFindModule_nodeCoreModules.ts @@ -0,0 +1,16 @@ +/// + +// @noImplicitAny: true + +// @Filename: /a.ts +////import fs = require("fs"); +////fs; + +verify.codeFixAvailable([{ + description: "Install '@types/node'", + commands: [{ + type: "install package", + file: "/a.ts", + packageName: "@types/node", + }], +}]);