TypeScript-如何键入自实例化函数



函数寄存器通过调用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;

最新更新