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
error TS2306: '...index.d.ts' is not a module
提问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.ts
file 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.json
looks 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.ts
was generated by tsc
, and I'm not sure why that very same tsc
isn'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.ts
that re-exports the definitions exposed in the library e.g.export * from './API' export * from './Decorators' ...
compile the library files with the
--declaration
flag to automatically generate the typings- add a
typings
entry topackage.json
pointing to the generatedindex.d.ts
file
创建一个
index.ts
重新导出库中公开的定义,例如export * from './API' export * from './Decorators' ...
使用
--declaration
标志编译库文件以自动生成类型- 添加一个
typings
条目以package.json
指向生成的index.d.ts
文件
To use the library:
要使用库:
- drop it in the
node_modules
folder 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 commonjs
and from what I understand, with systemjs
too. I do not know about amd
, and your generated typings look quite different from mine:
commonjs
根据我的理解,这个过程也可以很好地工作systemjs
。我不知道amd
,您生成的类型看起来与我的完全不同:
The generated index.d.ts
typically looks like
生成的index.d.ts
通常看起来像
export * from './API';
export * from './Decorators';
...
and the API.d.ts
file 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>;
}
....