gpt4 book ai didi

typescript - 如何导入类型定义模块? (错误 TS2656 : . ..不是模块)

转载 作者:搜寻专家 更新时间:2023-10-30 21:00:23 24 4
gpt4 key购买 nike

我有一个简单的 npm 模块,emitter20 ,我正在尝试向其中添加类型定义。这是其源代码的全部 20 行:

module.exports = function() {
var subscribers = []
return {
on: function (eventName, cb) {
subscribers.push({
eventName: eventName,
cb: cb
})
},
trigger: function (eventName, data) {
subscribers
.filter(function (subscriber) {
return subscriber.eventName === eventName
})
.forEach(function (subscriber) {
subscriber.cb(data)
})
}
}
}

这是 emitter20 项目根目录中的 index.d.ts 文件:

declare module 'emitter20' {
interface IEmitter {
on: (eventName: string, cb: (data?: any) => void) => void;
trigger: (eventName: string, data?: any) => void;
}
interface EmitterFactory {
new(): IEmitter;
}
export = IEmitter;
}

我也试过这个:

declare module 'emitter20' {
export interface IEmitter {
on: (eventName: string, cb: (data?: any) => void) => void;
trigger: (eventName: string, data?: any) => void;
}
export interface EmitterFactory {
new(): IEmitter;
}
}

我尝试像这样将它导入到我的项目中:

import IEmitter = require('emitter20')

export interface SwapManager extends IEmitter {
manager: any;
}

但我收到以下错误:

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

如何为 emitter20 模块定义和导入类型定义?

(旁白:Typescript 导入/导出...学习曲线的 hell !)

最佳答案

这里的问题是,这不是一个“合适的”JS 模块,请注意它实际上并没有公开任何类型本身,因此您将无法继承它……我认为。

如果这是一个返回类等的“普通”(?)或 ES6 JS 模块,您可以简单地使用一堆 export this;导出那个; export default function factory() 就像你试过的那样,但这是作为函数的模块之一,我的方法中使用了 export =,记录为:

For backwards compatibility with CommonJS and AMD style modules, TypeScript also supports export-equals declarations of the form export = Point. Unlike default export declarations, which are just shorthand for an export named default, export-equals declarations designate an entity to be exported in place of the actual module.

我知道以下两种获取此“类型”的方法:

方法 1:使用接口(interface):

优点:

  • 为您提供智能感知/自动完成和类型安全

缺点:

  • 不为显式类型声明公开接口(interface)(您不能声明具有该类型的变量)

ma​​in.ts

import * as emitterFactory from 'emitter20';

var emitterInstance = emitterFactory();
emitterInstance.on(...)

types.d.ts

declare module 'emitter20' {
interface IEmitter {
on: (eventName: string, cb: (data?: any) => void) => void;
trigger: (eventName: string, data?: any) => void;
}

interface IEmitterFactory {
(): IEmitter;
}

var EmitterFactory : IEmitterFactory;

export = EmitterFactory;
}

方法二:Function + Namespace 同名

优点:

  • 为您提供智能感知/自动完成和类型安全
  • 公开接口(interface)

缺点:

  • 看起来有点像黑魔法? :)

ma​​in.ts

import * as emitter from 'emitter20';

var emitterInstance : emitter.IEmitter = emitter();
emitterInstance.on("event", (data : any) => {
console.log(data.foo);
})
emitterInstance.trigger("event", {"foo": "bar"});

输出:

bar

types.d.ts

declare module 'emitter20' {

function Emitter(): Emitter.IEmitter;
namespace Emitter {
interface IEmitter {
on: (eventName: string, cb: (data?: any) => void) => void;
trigger: (eventName: string, data?: any) => void;
}
}


export = Emitter;
}

方法 3:声明一个全局命名空间

优点:

  • 为您提供智能感知/自动完成和类型安全
  • 公开接口(interface)
  • 看起来不像黑魔法

缺点:

  • Emitter 命名空间变得全局且随处可见(全局环境声明)

ma​​in.ts

import * as emitter from 'emitter20';

var emitterInstance : Emitter.IEmitter = emitter();

types.d.ts

declare namespace Emitter
{
export interface IEmitter {
on: (eventName: string, cb: (data?: any) => void) => void;
trigger: (eventName: string, data?: any) => void;
}

export interface IEmitterFactory {
(): Emitter.IEmitter;
}
}

declare module 'emitter20' {
var EmitterFactory : Emitter.IEmitterFactory;

export = EmitterFactory;
}

关于typescript - 如何导入类型定义模块? (错误 TS2656 : . ..不是模块),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37819659/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com