我阅读了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';

我做错了什么?


当前回答

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

其他回答

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

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

删除错误后。。。

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

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

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

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

// @ts-ignore: Unreachable code error

如果您正在导入一个第三方模块“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将进行编译。

这种方式对我有效:

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
    }