我阅读了TypeScript模块解析的工作原理。

我有以下存储库:@tsstack/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/@tsstack/di/dist/index.js”隐式具有“any”类型。

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

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

我做错了什么?


当前回答

如果您正在导入一个第三方模块“foo”,该模块在库本身或@types/foo包(从DefinelyTyped存储库生成)中不提供任何类型,那么可以通过在扩展名为.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量相当少,那么这特别容易。


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

declare module '*';

这样做的好处(也有缺点)是,您可以完全导入任何内容,TS将进行编译。

其他回答

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

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

您可以从npm安装它:

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

然后创建一个简单的声明器.json文件:

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

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

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

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

它不会生成强大的类型,在这一过程中您可能会遇到许多类型,但使用它比不使用它要好得多

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

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

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

删除错误后。。。

澄清:当我们在*.d.ts文件中声明一个模块时,Typescript编译器会自动将其作为环境模块(不需要显式导入的模块)。一旦我们指定了导入。。。从…起该文件现在成为一个正常(ES6)模块,因此不会自动拾取。因此,如果您仍然希望它作为环境模块,请使用不同的导入样式,如下所示:

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

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

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

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

这应该是工作

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

在我的案例中,解决方法是终止终端进程,删除node_modules,清除节点包管理器缓存,重新安装,然后重新加载编辑器。

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

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

React的create-React应用程序自动生成的配置将该标志设置为true