ChatGPT解决这个技术问题 Extra ChatGPT

找不到模块“模块名称”的声明文件。 '/path/to/module-name.js' 隐含一个 'any' 类型

我阅读了 TypeScript module resolution 的工作原理。

我有以下存储库:@ts-stack/di。编译后的目录结构如下:

├── dist
│   ├── annotations.d.ts
│   ├── annotations.js
│   ├── index.d.ts
│   ├── index.js
│   ├── injector.d.ts
│   ├── injector.js
│   ├── profiler.d.ts
│   ├── profiler.js
│   ├── providers.d.ts
│   ├── providers.js
│   ├── util.d.ts
│   └── util.js
├── LICENSE
├── package.json
├── README.md
├── src
│   ├── annotations.ts
│   ├── index.ts
│   ├── injector.ts
│   ├── profiler.ts
│   ├── providers.ts
│   └── util.ts
└── tsconfig.json

在我的 package.json 中,我写了 "main": "dist/index.js"

在 Node.js 中一切正常,但 TypeScript:

import {Injector} from '@ts-stack/di';

找不到模块“@ts-stack/di”的声明文件。 '/path/to/node_modules/@ts-stack/di/dist/index.js' 隐含地具有 'any' 类型。

然而,如果我按如下方式导入,那么一切正常:

import {Injector} from '/path/to/node_modules/@ts-stack/di/dist/index.js';

我究竟做错了什么?

对于正在寻找可以轻松找到类型定义的地方的人,您可以使用官方 TypeScript 类型搜索:typescriptlang.org/dt/search?search=

C
Community

这是另外两个解决方案

当模块不是您的时 - 尝试从 @types 安装类型:

npm install -D @types/module-name

如果出现上述安装错误 - 尝试将 import 语句更改为 require

// import * as yourModuleName from 'module-name';
const yourModuleName = require('module-name');

如果找不到名称,则需要为 TypeScript 2.0 运行此命令:npm install @types/node --save-dev
如果模块没有 @types 包怎么办?
示例用法:const mdbreact = require('mdbreact'); const { Button, Card, CardBody, CardText, CardTitle, CardImage } = mdbreact;
我正在使用带有 YARN 的 react typescript 项目,只需要工作。谢谢你const yourModuleName = require('module-name');
@DanielKmak 我有同样的问题。看起来只是使用 require 代替工作。但仅供参考:如果您导入的内容足够流行,有一个名为“DefiniteTyped”的存储库(在下面的另一个答案中提到)可以提供类型。
S
Syntle

如果您在库本身或 @types/foo 包(从 DefinitelyTyped 存储库生成)中导入不提供任何类型的第三方模块 'foo',则可能会出现此错误通过在具有 .d.ts 扩展名的文件中声明模块来离开。 TypeScript 在查找普通 .ts 文件的相同位置查找 .d.ts 文件:如 tsconfig.json 中的“files”、“include”和“exclude”下指定的。

// foo.d.ts
declare module 'foo';

然后,当您导入 foo 时,它只会输入为 any

或者,如果您想滚动自己的类型,您也可以这样做:

// foo.d.ts
declare module 'foo' {
    export function getRandomNumber(): number
} 

然后这将正确编译:

import { getRandomNumber } from 'foo';
const x = getRandomNumber(); // x is inferred as number

您不必为模块提供完整的类型,对于您实际使用的位(并且需要正确的类型)就足够了,因此如果您使用相当少量的 API,这将特别容易。

另一方面,如果您不关心外部库的类型并希望将所有没有类型的库作为 any 导入,则可以将其添加到扩展名为 .d.ts 的文件中:

declare module '*';

这样做的好处(和缺点)是你可以导入任何东西,并且 TS 会编译。


编译器在哪里查找 d.ts 文件?您是否应该提供任何配置,例如 typeRoots
@Tom 它在查找普通 .ts 文件的相同位置查找 .d.ts 文件:如 tsconfig.json 中指定的“文件”、“包含”和“排除”。我不建议为此目的使用 typeRoots:这是用于外部类型模块(即 node_modules/@types)的位置,而不是单独的 .d.ts 文件。
为了使其工作,我必须将 declare module '...' 作为 module.d.ts 文件中的第一行代码,并在模块块中包含所有导入,而不是在它之前。在我这样做之前,编译器说它找不到模块。
declare module '*' 会确保只编译没有类型的包,还是会干扰有类型的包?
如果您在使用 ts-node 时遇到此类错误,请查看 ts-node 文档 Help! My Types Are Missing!。我花了几个小时试图找出为什么编译器看不到我的 .d.ts
m
mb21

如果您需要快速修复,只需在导入行之前添加:

// @ts-ignore

这会在更高版本的 eslint 中导致错误:error Do not use "// @ts-ignore" comments because they suppress compilation errors @typescript-eslint/ban-ts-ignore
@Hykilpikonna 我相信您可以在使用 // @ts-ignore 之前添加 /* eslint-disable */ 以禁用 eslint,然后在问题代码行之后添加 /* eslint-enable */ 以重新启用文件其余部分的 eslint。
您还可以在 ts 行之前添加 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
这不是解决办法或答案,而是压制投诉的一种方式。
m
mikemaccana

对于您正在安装自己的 npm 包的情况

如果您使用第三方软件包,请参阅 my answer below

package.json 中的 "main": "dist/index.js" 中删除 .js

"main": "dist/index",

还要添加 typings in package.json per the TypeScript docs

"main": "dist/index",
"typings": "dist/index",

文件夹 dist 是 TS 编译器存储模块文件的位置。


我对此有点挣扎:当您拥有自己的包时,请务必删除包的 dist 文件夹(或项目中的整个 node_modules)的旧内容,然后再次运行您的捆绑程序。即使在此编辑之后,我仍然在 dist 中有旧的 index.js,这对我造成了警告。
谢谢你 - 你的英语不是很清楚,但这有帮助,我的 typings 不正确。我进行了一些更改以使答案更清晰。
@optimista 我也遇到了陈旧的 dist 问题。 rm -rf ./dist/* ; tsc
就我而言,真正有效的是:"main": "dist/index.js", "typings": "src/index"
c
coudy.one

由于 Javascript 缺乏约束,TypeScript 基本上是在实现规则并为您的代码添加类型以使其更清晰、更准确。 TypeScript 要求您描述您的数据,以便编译器可以检查您的代码并发现错误。如果您使用不匹配的类型、超出范围或尝试返回不同的类型,编译器会通知您。因此,当您将外部库和模块与 TypeScript 一起使用时,它们需要包含描述该代码中类型的文件。这些文件称为类型声明文件,扩展名为 d.ts。大多数 npm 模块的声明类型已经编写好了,您可以使用 npm install @types/module_name 包含它们(其中 module_name 是您想要包含其类型的模块的名称)。

但是,有些模块没有其类型定义,为了消除错误并使用 import * as module_name from 'module-name' 导入模块,请在项目的根目录中创建一个文件夹 typings,在其中创建一个新文件夹您的模块名称并在该文件夹中创建一个 module_name.d.ts 文件并写入 declare module 'module_name'。之后,只需转到您的 tsconfig.json 文件并在 compilerOptions 中添加 "typeRoots": [ "../../typings", "../../node_modules/@types"](使用正确的文件夹相对路径),让 TypeScript 知道它可以在哪里找到您的库和模块的类型定义并添加一个新的属性 "exclude": ["../../node_modules", "../../typings"] 到文件。这是您的 tsconfig.json 文件应如下所示的示例:

{
    "compilerOptions": {
        "module": "commonjs",
        "noImplicitAny": true,
        "sourceMap": true,
        "outDir": "../dst/",
        "target": "ESNEXT",
        "typeRoots": [
            "../../typings",
            "../../node_modules/@types"
        ]
    },
    "lib": [
            "es2016"
    ],
    "exclude": [
        "../../node_modules",
        "../../typings"
    ]
}

通过这样做,错误将消失,您将能够坚持最新的 ES6 和 TypeScript 规则。


仅当我将类型文件命名为 index.d.ts 时,它才对我有用。除此之外,这是唯一对我有用的解决方案。
也为我工作(不需要将名称更改为 index.d.ts)。对于那些使用默认应用程序结构 ng new app-name 的人,您可能需要您的路径具有一层,例如:"../node_modules""../typings" 等。另外,请确保 module-name 部分6} 语句与您在原始文件中导入它的方式完全相同。例如:在我的情况下,它必须是:declare module 'videojs-record/dist/videojs.record.js',因为这就是我在原始文件中导入它的方式。
如果我的 tsconfig.json 文件的 "include" 中有一个文件夹(我的应用程序/组件所在的位置)与 typings 文件夹所在的位置不同,那么我不需要添加 "excludes":... 部分对吗?
a
aldo.roman.nurena

对于其他阅读本文的人,请尝试将您的 .js 文件重命名为 .ts

编辑:您还可以将 "allowJs": true 添加到您的 tsconfig 文件中。


我已将 allowJs 设置为 true 但它不起作用
"allowJs": true 为我工作,谢谢
你真是个天才,好先生。谢谢!
C
Christos Lytras

这种方式对我有用:

1.在index.d.ts等声明文件中添加自己的声明(可能在项目根目录下)

declare module 'Injector';

2. 将你的 index.d.ts 添加到 tsconfig.json

  {
    "compilerOptions": {
        "strictNullChecks": true,
        "moduleResolution": "node",
        "jsx": "react",
        "noUnusedParameters": true,
        "noUnusedLocals": true,
        "allowSyntheticDefaultImports":true,
        "target": "es5",
        "module": "ES2015",
        "declaration": true,
        "outDir": "./lib",
        "noImplicitAny": true,
        "importHelpers": true
      },
      "include": [
        "src/**/*",
        "index.d.ts",   // declaration file path
      ],
      "compileOnSave": false
    }

这为我解决了。我还在我的项目根目录中添加了一个名为 typings 的文件夹。在里面我添加了 .d.ts 文件
L
Luke Garrigan

不幸的是,包编写者是否会为声明文件而烦恼,这不在我们的掌控之中。我倾向于做的是有一个像 index.d.ts 这样的文件,其中包含来自各种包的所有缺少的声明文件:

索引.d.ts:

declare module 'v-tooltip';
declare module 'parse5';
declare module 'emoji-mart-vue-fast';

并在您的 tsconfig.js 中引用它:

"include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "tests/**/*.ts",
    "tests/**/*.tsx",
    "index.d.ts" // this
  ]

K
Kia Boluki

只需在项目的根目录中创建一个名为 typings.d.ts 的文件。在此文件中只需添加 declare module <module_name>。这里,module_name 可以是您要导入的任何模块的名称。最后,打开 tsconfig.json 文件并将文件 typings.d.ts 包含在名为 include array 的数组中。

// typings.d.ts 
declare module 'abc-module';

// tsconfig.json 
{
  ...
"include": [
    "src", "typings.d.ts"
  ]
}

// BOOM, Problem solved!!!

这种技术为您的模块提供了一个名为“any”的类型。欲了解更多信息:https://medium.com/@steveruiz/using-a-javascript-library-without-type-declarations-in-a-typescript-project-3643490015f3


S
Sanchitos

这就是我让它工作的方式。

在我的例子中,我使用了一个没有定义类型的库:react-mobile-datepicker

一个。在 /src 内创建一个文件夹。在我的例子中,我使用了这个路径:/src/typings/

湾。创建一个 .d.ts 文件。对于我的示例:/src/typings/react-mobile-datepicker.d.ts

C。我使用以下代码来扩展其属性并使其类型安全:

declare module 'react-mobile-datepicker' {
  class DatePicker extends React.Component<DatePickerProps, any> {}

  interface DatePickerProps {
    isPopup?: boolean;
    theme?: string;
    dateConfig?: DatePickerConfig;
  }

  export interface DatePickerConfig {
    prop1: number;
    pro2: string;
  }
  export default DatePicker;
}

d。像通常在使用 3rd 方库的地方一样导入您的类型。

import DatePicker, { DatePickerConfig, DatePickerConfigDate } from 'react-mobile-datepicker';

e.更改 tsconfig.json 并添加这段代码:

{
  "compilerOptions": {
    //...other properties
    "typeRoots": [
      "src/typings",
      "node_modules/@types"
    ]
  }}

我用作来源的文章的链接:

https://templecoding.com/blog/2016/03/31/creating-typescript-typings-for-existing-react-components

https://www.credera.com/insights/typescript-adding-custom-type-definitions-for-existing-libraries


A
Abanoub Hany

解决方案:您所要做的就是编辑您的 TypeScript 配置文件 tsconfig.json 并添加一个新的键值对作为

"compilerOptions": {
"noImplicitAny": false
}

这不会只是删除错误消息而不是解决问题吗?
这将对您的打字稿类型检查产生更广泛的影响,而不仅仅是使此导入工作。谨慎行事并阅读此设置以确保您想要所有副作用。
如果您发现自己将其关闭,您不妨在 javascript 中运行。此答案中的其他选项是更好的选择。当然,任何类型都为您提供了一种将对象变形并将圆形钉子塞入方孔的方法,但是您失去了对预期输入的了解。您可以添加类型保护,但是在编译时没有任何这些,类型保护是在运行时完成的。
H
Hari Reddy

一个简单的修复:

// example.d.ts
declare module 'foo';

如果你想声明一个对象的接口(推荐用于大型项目),你可以使用:

// example.d.ts
declare module 'foo'{
    // example
    export function getName(): string
}

怎么用?简单的..

const x = require('foo') // or import x from 'foo'
x.getName() // intellisense can read this

I
Ilyas Assainov

我在这里尝试了一切,但对我来说这是一个完全不同的问题:我必须从我的 *.d.ts 中删除任何导入语句:

import { SomeModuleType } from '3rd-party-module';

删除错误后消失...

澄清:当我们在 *.d.ts 文件中声明模块时,Typescript 编译器会自动将其作为 ambient 模块(您不需要导入的模块)明确)。一旦我们指定了 import ... from ...,文件现在就变成了一个普通的 (ES6) 模块,因此不会被自动拾取。因此,如果您仍然希望它充当 ambient 模块,请使用不同的导入样式,如下所示:

type MyType: import('3rd-party-module').SomeModuleType;

这是一个动态导入并返回一个承诺......它只能在异步上下文中工作。不过好消息。
实际上,如果您遵循此问题的任何其他赞成的答案,但您的 *.d.ts 文件中恰好有一个正常的“导入”,那么您的 *.d.ts 文件将被静默忽略。
t
thiagosilva

检查 "tsconfig.json" 文件中的编译选项 "include""exclude"。如果它不存在,只需通过通知您的 root 目录来添加它们。

// tsconfig.json
{
  "compilerOptions": {
  ...
  "include": [
    "src", 
  ],
  "exclude": [
    "node_modules", 
  ]
}

我只是通过从 "exclude" 中删除扩展语句 "*.spec.ts" 解决了我的愚蠢问题,因为在这些文件中包含 "import" 时,总是会出现问题。


M
MANAN

如果您已经安装了模块并且仍然收到错误,一个简短而有效的解决方案是通过在该行上方添加以下行来忽略错误消息

// @ts-ignore: Unreachable code error

O
Ogglas

@ktretyak 和 @Retsam 的答案是正确的,但我想添加一个完整的实时示例以及我必须做的事情:

错误:

错误 TS7016 (TS) 找不到模块“react-region-select”的声明文件。 'C:/Repo/node_modules/react-region-select/lib/RegionSelect.js' 隐含了一个 'any' 类型。尝试 npm i --save-dev @types/react-region-select 如果它存在或添加一个包含`declare module的新声明(.d.ts)文件

运行 npm i --save-dev @types/react-region-select 给出错误:

npm 错误!代码 E404 npm 错误! 404 未找到 - 获取 https://registry.npmjs.org/@types%2freact-region-select - 未找到 npm 错误! 404 '@types/react-region-select@latest' 不在 npm 注册表中。 npm 错误! 404 你应该让作者发布它(或自己使用名称!)npm ERR! 404 请注意,您也可以从 npm tarball、文件夹、http url 或 git url 安装。

鉴于 create-react-app 创建了一个名为 react-app-env.d.ts 的文件,我尝试将 declare module 'react-region-select'; 放入其中,但仍然收到错误消息。

然后我在 src 中创建了一个名为 typings 的新文件夹和一个名为 react-region-select.d.ts 的文件。在那里我声明了这样的模块:

declare module 'react-region-select';

这样做之后,错误消失了,我可以像文档所述那样导入它:

import RegionSelect from "react-region-select"; 

https://github.com/casavi/react-region-select


K
Kanthavel

我在使用带有用打字稿编写的反应应用程序的节点模块时遇到了同样的问题。该模块已使用 npm i --save my-module 成功安装。它是用 javascript 编写的并导出一个 Client 类。

和:

import * as MyModule from 'my-module';
let client: MyModule.Client = new MyModule.Client();

编译失败并出现以下错误:

Could not find a declaration file for module 'my-module'. 
'[...]/node_modules/my-module/lib/index.js' implicitly has an 'any' type.
  Try `npm install @types/my-module` if it exists or add a new declaration (.d.ts) file containing `declare module 'my-module';`

@types/my-module 不存在,因此我在导入 my-module 的文件旁边添加了一个 my-module.d.ts 文件,其中包含建议的行。然后我得到了错误:

Namespace '"my-module"' has no exported member 'Client'.

如果我在 js 应用程序中使用它,客户端实际上已导出并正常工作。此外,上一条消息告诉我编译器正在查找正确的文件(/node_modules/my-module/lib/index.jsmy-module/package.json "main" 元素中定义)。

我通过告诉编译器我不关心隐式 any 解决了这个问题,也就是说,我将 tsconfig.json 文件的以下行设置为 false

    "noImplicitAny": false,

我的意思是,这可行,但您将失去严格键入其余代码的能力。这不是一个很好的解决方法。
A
Arthur Fiorette

我在许多项目中的许多软件包都面临同样的问题。所以我创建了 Declarator,这是一个自动生成类型声明的 npm 包。

它基本上通过在后台运行 tsc --emitDeclarationOnly 来工作。

你可以从 npm 安装它:

npm install --save-dev declarator
yarn add -D declarator

然后创建一个简单的 declarator.json 文件:

{
  "$schema": "https://raw.githubusercontent.com/ArthurFiorette/declarator/master/schema.json",
  "packages": ["package1","package2"]
}

并创建一个脚本来运行它:

使用 postinstall 脚本将在每次安装包时运行它,可能很有用

{
  "scripts": {
    "postinstall": "declarator"
  }
}

它不会生成强大的类型,并且您可能会在此过程中遇到许多 any 类型,但有总比没有好得多

阅读更多:https://github.com/ArthurFiorette/declarator#readme


L
Leo

我也得到了这个,让我困惑了一段时间,即使模块和类型已经安装并重新加载了我的 IDE 几次。

在我的情况下修复它的是终止终端进程,删除 node_modules,清除节点包管理器缓存并执行新的 install,然后重新加载编辑器。


B
Bouke Versteegh

如果您在 Webstorm 中看到此错误,并且您刚刚安装了该软件包,则可能需要重新启动 typescript 服务,然后它才能将其拾取。

打开帮助菜单

查找操作

搜索重启 Typescript 服务

https://i.stack.imgur.com/NtIPY.png

https://i.stack.imgur.com/AbaFI.png


B
Binh Ho

这对我有用。

// modules.d.ts 
declare module 'my-module';
// tsconfig.json 
{
  ...
  "include": [
    ...
    "src", "modules.d.ts"
  ]
}

// Import
import * as MyModule from 'my-module'
...
const theModule = MyModule()
...

M
Muhammad Monis Mazhar

对我有用的是将依赖项安装为开发依赖项。上述禁用隐式类型检查的解决方案有效,但这使我无法利用严格类型的代码。因此,您要做的就是将所有 @types 模块安装附加到 --save-dev 标志。希望对你也有用


t
tyirvine

Retsam's answer 的基础上,您还可以在 yourDeclarations.d.ts 文件中使用通配符 (*)。例如,如果您尝试导入文件,例如 .css.webp 文件,您可以在文件类型声明的开头放置一个 *。它看起来像这样⤵︎

declare module '*.webp';

现在,您可以导入所有需要的 .webp 文件,而不会出现任何 linting 错误。


K
Karan Patokar

如果导入不适合您

import * as html2pdf from 'html2pdf.js';

注释代码,将下面的脚本文件保留在 index.html 中,如官方文档中给出的那样。

<script src="https://rawgit.com/eKoopmans/html2pdf/master/dist/html2pdf.bundle.min.js"></script>

并在您正在使用的组件中声明 html2pdf 变量。

declare var html2pdf: any;

而已。我被这个问题困了2天,但终于解决了。


j
jsina

创建具有任意名称和 .d.ts 扩展名的文件。

例如:index.d.ts

tsconfig.json 文件的 include 键下推送此文件名:

  "include": [
    "src",
    "index.d.ts"
  ]

S
Stive

您是否需要创建扩展名为 .d.ts 的文件。

tsconfig.json 文件的 include 键下推送此文件名:

  "include": [
    "src",
    "index.d.ts"
  ]

这应该是工作


F
Francesco Meli

从打字稿文档:

请注意,“typings”字段与“types”同义,也可以使用。

另请注意,如果您的主声明文件名为 index.d.ts 并且位于包的根目录(在 index.js 旁边),则不需要标记 types 属性,但建议这样做。

出于某种原因,我的“类型”属性指向一些 main.d.ts。从 package.json 中删除该行并开始工作。


G
Gabriel soft

在大多数情况下,您可能会为您的依赖项安装一个类型包,无论哪种方式,您都可以在 tsconfig.json 文件中添加 allowJs -> true


u
user3291332

对于在 React 中遇到此错误的人,请在 tsconfig.json 中设置

"compilerOptions" : {
  ...
  "strict": false,
  ...
}

React 的 create-react-app 自动生成的配置将该标志设置为 true


strict:false 有什么缺点吗?
F
Foysal imran

您所要做的就是编辑您的 TypeScript 配置文件 (tsconfig.json) 并添加一个新的键值对作为 "noImplicitAny": false


这将抵消使用 Typescript 的好处。您基本上是在消除警告而不是修复它

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅