我有档案my-module.ts
:
declare module "my-module" {
interface main {
(string):string,
methodName():any,
propertyName:any,
objectName:Object
}
export default main;
}
并在文件test.ts
中使用时:
import * as MyModule from "my-module";
var s = MyModule('test');
我收到错误Cannot invoke an expression whose type lacks a call signature.
为什么会这样,以及如何解决?
更新
根据Joe Clay的建议,如果我们将代码更改为:
declare module "my-module" {
interface main {
(string):string,
methodName():any,
propertyName:any,
objectName:Object
}
var myModule: main;
export default myModule;
}
然后尝试使用它:
import myModule from "my-module";
var s = myModule('test');
它会生成以下JavaScript:
var my_module_1 = require("my-module");
var s = my_module_1["default"]('test');
引发错误my_module_1.default is not a function
。
更新
以下更改解决了当前问题:
declare module "my-module" {
interface main {
(string):string,
methodName():any,
propertyName:any,
objectName:Object
}
var myModule: main;
export = myModule; // <= Here's the change
}
并使用它:
import * as myModule from "my-module";
然而,这给我带来了另一个问题。我展示了一个my-module
的简化示例,而真正的一个有几个类,enum
- s要导出。但是,如上所述,我们不再能做到这一点。
环境类和enum
- s应该使用export enum Name{}
和export class Name
导出,但在使用export = myModule
时不允许使用此语法,从而产生错误:{ {1}}。
现在如何纠正这个? :)
更麻烦的是,我有另一个具有An export assignment cannot be used in a module with other exported elements.
类型属性的模块,如果我声明为my-module
,我将获得properName: MyModule
。我不明白这意味着什么。
答案 0 :(得分:2)
a)如果您有默认导出,导入语法只是import MyModule from "my-module";
- 您不需要* as
。
b)您无法呼叫接口。您可以调用实现的内容,但尝试执行MyModule()
并不合理。
修改强>
响应更新的代码 - this is a pretty common issue when you're trying to use TypeScript's ES6 imports with a CommonJS module。微软坚持在可能的情况下坚持使用规范,而不是使用任何魔法将module.exports
转换为ES6默认导出 - 技术上他们可能在这样做时是正确的,但考虑到Babel (可能是最流行的JavaScript转换器)转换就好了,我真的希望他们也可以将它添加到TypeScript中。
建议的方法是将导入恢复为import * as MyModule from "my-module";
语法并修改声明,如下所示:
declare module "my-module" {
interface main {
(string):string,
methodName():any,
propertyName:any,
objectName:Object
}
var myModule: main;
export = myModule; // <= Here's the change
}
希望能够为您提供您正在寻找的结果。
编辑2:
当您想要在声明中开始定义自己的类型时,它会变得更复杂,而不仅仅是原语 - 但不是太复杂。一个很好的例子是the type definitions for body-parser
。我不会在这里复制整件事,因为我的答案已经变得很疯狂,但需要注意的是:
namespace
,将其作为主要导出,然后从中导出其他内容。bodyParser
定义为函数,然后定义具有相同名称的命名空间。这些将合并,这意味着命名空间中的导出将显示为函数的属性(例如bodyParser()
和bodyParser.json()
都可用)。基本上,我能给你的最好建议是浏览DefinitelyTyped存储库,找到你熟悉的模块,看看他们的定义是如何创建的 - 这是学习如何自己完成的最好方法。