错误TS2306:'... index.d.ts'不是模块

时间:2016-09-01 15:53:20

标签: typescript amd typescript-typings

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

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

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

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

生成的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;
});

根据我的口味,这是很多AMD模块,但我可以忍受它。生成的代码看起来效果很好。

生成的.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";
}

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

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

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

但问题是

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

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

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

但是typescript编译器会抛出以下错误

 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.

老实说,我无法弄清楚我应该在这做什么。 index.d.ts生成了tsc,我不确定为什么同一个tsc无法在另一个项目中使用它。

1 个答案:

答案 0 :(得分:4)

上面的讨论太久了,但这里是我的TL; DR来创建一个库:

  • 创建一个index.ts,重新导出库中公开的定义,例如

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

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

使用该库:

  • 将其放在node_modules文件夹中,与任何其他库一样
  • 只需import * as mylib from 'mylib':它会自动导入所有导出的定义打字

此过程与commonjs以及我所理解的systemjs完全正常。我不知道amd,你生成的打字与我的不同:

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

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

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>;
}
....