函数寄存器通过调用Register('something')
来实例化。Typescript表示,只有在void
返回函数上使用new
时,这才有可能。在这种情况下,Register
正在返回其自身的一个实例。我应该如何在Typescript中键入这个?
module Register {
export function Register(x: string): Instance {
if (!(this instanceof Register)) {
return new Register(x)
}
this.value = x
}
...
export interface Instance {
new(x: string): Instance;
...
}
}
export = Register
也许你的例子被简化了,你正试图在后台实现更复杂的东西,但如果我正确理解你的代码,你只想返回一个没有New运算符的Register函数实例。
我能想到的唯一选项是欺骗TS编译器,将返回类型指定为void,然后在变量中使用any类型。
module Register {
export function Register(x: string): void {
if (!(this instanceof Register)) {
return new Register(x);
}
this.value = x;
}
export interface Instance {
new (x: string): Instance;
value: string;
}
}
export = Register;
var rega: any = Register.Register("something");
console.log(rega.value); // something
更新:由于将any
指定为每个变量的显式类型有问题,因此可以使用Object.create()而不是新的运算符:
module Register {
export function Register(x: string): Instance {
var r = Object.create(Register);
r.value = x;
return r;
}
export interface Instance {
new (x: string): Instance;
value: string;
}
}
export = Register;
var rega = Register.Register("something");
console.log(rega.value); // something
我怀疑你遇到了和我遇到的同样的问题(这让我来到这里)。
我试图为现有的纯JavaScript(.js
)项目添加一些TypeScript类型定义(.d.ts
)。
JavaScript源代码是一个传统的constructor
函数(带有原型类方法),它可以检测是否在没有new
的情况下调用它,并做正确的事情:
const MyObject = function (options) {
if (!(this instanceof MyObject)) {
return new MyObject(options);
}
// ...
}
MyObject.prototype.myMethod = function() {
// Do something...
}
module.exports = MyObject;
我对为这种JavaScript对象添加TypeScript类型的"正确"方法的理解是使用interface
:
declare interface MyObject {
/**
* Constructor interface
*/
new (options?: Options): this;
/**
* Functional interface
*/
(options?: Options): this;
/**
* JSDoc ftw!
*/
myMethod(): void;
}
// Needed so we can export a variable, not just a type
declare const MyObject: MyObject;
// Since the JavaScript is not exporting a "module" (object with a `default` parameter):
export = MyObject;