typescript 错误 TS2306:“...index.d.ts”不是模块

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39276023/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 03:48:41  来源:igfitidea点击:

error TS2306: '...index.d.ts' is not a module

typescriptamdtypescript-typings

提问by LordOfThePigs

I'm trying to write a lib in Typescript that I want to use in various other typescript or JS projects. All of the those other projects run in browsers.

我正在尝试在 Typescript 中编写一个库,我想在各种其他打字稿或 JS 项目中使用它。所有这些其他项目都在浏览器中运行。

My Typescript lib project has multiple files, and each file is a React component with 1 class and 1-2 interfaces (Component + Props + State, for those that are familiar with React).

我的 Typescript lib 项目有多个文件,每个文件都是一个 React 组件,有 1 个类和 1-2 个接口(Component + Props + State,对于熟悉 React 的人来说)。

I want my component library to be importable as an AMD module by the other projects, and I want all of the compiled JS code to be bundled in a single file as part of the library's build process.

我希望我的组件库可以作为 AMD 模块被其他项目导入,并且我希望所有编译的 JS 代码都捆绑在一个文件中,作为库构建过程的一部分。

So far I've managed to set everything up so that my lib compiles. I've set up the compiler with the following options : jsx: "react", declaration: true, module: "amd"

到目前为止,我已经设法设置了所有内容,以便我的 lib 进行编译。我已经使用以下选项设置了编译器:jsx: "react", declaration: true, module: "amd"

The generated code for the lib looks like:

为 lib 生成的代码如下所示:

define("epb-widget/WidgetItemNav", ["require", "exports", "react"], function (require, exports, React) {
    "use strict";
    exports.WidgetItemNav = ...;
});
define("epb-widget/WidgetItemInfo", ["require", "exports", "react"], function (require, exports, React) {
    "use strict";
    exports.WidgetItemInfo = ...;
});
define("epb-widget/WidgetItem", ["require", "exports", "react", "epb-widget/WidgetItemNav", "epb-widget/WidgetItemInfo"], function (require, exports, React, WidgetItemNav_1, WidgetItemInfo_1) {
    "use strict";
    exports.WidgetItem = ...;
});
define("epb-widget/WidgetOptions", ["require", "exports", "react"], function (require, exports, React) {
    "use strict";
    exports.WidgetOptions = ...;
});
define("epb-widget/Widget", ["require", "exports", "react", "epb-widget/WidgetItem", "epb-widget/WidgetOptions"], function (require, exports, React, WidgetItem_1, WidgetOptions_1) {
    "use strict";
    exports.Widget = ...;
});
define("epb-widget", ["require", "exports", "epb-widget/Widget", "epb-widget/WidgetItem", "epb-widget/WidgetItemInfo", "epb-widget/WidgetItemNav", "epb-widget/WidgetOptions"], function (require, exports, Widget_1, WidgetItem_2, WidgetItemInfo_2, WidgetItemNav_2, WidgetOptions_2) {
    "use strict";
    exports.Widget = Widget_1.Widget;
    exports.WidgetItem = WidgetItem_2.WidgetItem;
    exports.WidgetItemInfo = WidgetItemInfo_2.WidgetItemInfo;
    exports.WidgetItemNav = WidgetItemNav_2.WidgetItemNav;
    exports.WidgetOptions = WidgetOptions_2.WidgetOptions;
});

That's a lot of AMD modules for my taste, but I can live with it. The generated code looks like it would work well.

有很多 AMD 模块符合我的口味,但我可以接受。生成的代码看起来运行良好。

The generated .d.tsfile looks like that:

生成的.d.ts文件如下所示:

declare module "epb-widget/WidgetItemNav" {
    import * as React from "react";
    export interface WidgetItemNavProps {
        ...
    }
    export class WidgetItemNav extends React.Component<WidgetItemNavProps, void> {
        ...
    }
}
declare module "epb-widget/WidgetItemInfo" {
    export interface WidgetItemInfoProps {
        ...
    }
    export const WidgetItemInfo: (props: WidgetItemInfoProps) => JSX.Element;
}
declare module "epb-widget/WidgetItem" {
    export interface WidgetItemProps {
        ...
    }
    export const WidgetItem: (props: WidgetItemProps) => JSX.Element;
}
declare module "epb-widget/WidgetOptions" {
    import * as React from "react";
    export interface WidgetOptionsProps {
        ...
    }
    export interface WidgetOptionsState {
        ...
    }
    export class WidgetOptions extends React.Component<WidgetOptionsProps, WidgetOptionsState> {
        ...
    }
}
declare module "epb-widget/Widget" {
    import * as React from "react";
    import { WidgetItemProps } from "epb-widget/WidgetItem";
    export interface WidgetProps {
        ...
    }
    export interface WidgetState {
        ...
    }
    export class Widget extends React.Component<WidgetProps, WidgetState> {
        ...
    }
}
declare module "epb-widget" {
    export { Widget, WidgetProps } from "epb-widget/Widget";
    export { WidgetItem, WidgetItemProps } from "epb-widget/WidgetItem";
    export { WidgetItemInfo, WidgetItemInfoProps } from "epb-widget/WidgetItemInfo";
    export { WidgetItemNav, WidgetItemNavProps } from "epb-widget/WidgetItemNav";
    export { WidgetOptions, WidgetOptionsProps } from "epb-widget/WidgetOptions";
}

Again, that looks quite reasonable. And that was all output directly by the Typescript compiler.

同样,这看起来很合理。这些都是 Typescript 编译器直接输出的。

Finally, this library is an npm module, and its package.jsonlooks like this

最后,这个库是一个 npm 模块,它package.json看起来像这样

{
  "name": "epb-widget",
  "version": "1.0.0",
  "description": "...",
  "main": "./dist/index.js",
  "typings": "./dist/index",
  "globalDependencies": {...},
  "devDependencies": {...}
}

But here's the problem

但问题来了

When I try to use the library in one of my projects, it doesn't actually work.

当我尝试在我的一个项目中使用该库时,它实际上不起作用。

I simply try import the classes like this:

我只是尝试导入这样的类:

import {Widget, WidgetProps, WidgetItem} from "epb-widget";

but the typescript compiler throws the following error

但是打字稿编译器会抛出以下错误

 error TS2656: Exported external package typings file '.../node_modules/epb-widget/dist/index.d.ts' is not a module. Please contact the package author to update the package definition.

I honestly can't figure out what I should do here. index.d.tswas generated by tsc, and I'm not sure why that very same tscisn't able to consume it in another project.

老实说,我不知道我应该在这里做什么。index.d.ts由 生成tsc,我不确定为什么它tsc不能在另一个项目中使用它。

回答by Bruno Grieder

This is too long to go into our discussion above but here is my TL;DR to create a library:

这太长了,无法进入我们上面的讨论,但这是我创建库的 TL;DR:

  • create an index.tsthat re-exports the definitions exposed in the library e.g.

    export * from './API'
    export * from './Decorators'
    ...
    
  • compile the library files with the --declarationflag to automatically generate the typings

  • add a typingsentry to package.jsonpointing to the generated index.d.tsfile
  • 创建一个index.ts重新导出库中公开的定义,例如

    export * from './API'
    export * from './Decorators'
    ...
    
  • 使用--declaration标志编译库文件以自动生成类型

  • 添加一个typings条目以package.json指向生成的index.d.ts文件

To use the library:

要使用库:

  • drop it in the node_modulesfolder like any other library
  • simply import * as mylib from 'mylib': it will automatically import all the exported definitions andthe typings
  • node_modules像任何其他库一样将其放入文件夹中
  • 只是import * as mylib from 'mylib':它会自动导入所有导出的定义对分型

This process works perfectly fine with commonjsand from what I understand, with systemjstoo. I do not know about amd, and your generated typings look quite different from mine:

commonjs根据我的理解,这个过程也可以很好地工作systemjs。我不知道amd,您生成的类型看起来与我的完全不同:

The generated index.d.tstypically looks like

生成的index.d.ts通常看起来像

export * from './API';
export * from './Decorators';
...

and the API.d.tsfile will typically look like

并且API.d.ts文件通常看起来像

import * as stream from 'stream';
import * as net from 'net';
import * as url from 'url';
export interface Factory {
    end(): Promise<void>;
}
export interface ChannelFactory extends Factory {
    getChannel(name: string, closeListener?: () => void): Promise<Channel>;
    existsChannel(name: string): Promise<boolean>;
}
....