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

时间:2014-10-10 09:04:58

标签: typescript

通过调用Register('something')来实例化函数寄存器。 Typescript说这只有在new返回函数上使用void时才有可能。在这种情况下,Register正在返回自身的实例。我应该如何在打字稿中输入?

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

2 个答案:

答案 0 :(得分:2)

也许您的示例已经简化了,并且您正在尝试实现更复杂的内容,但是如果我正确理解您的代码,您只想返回Register函数的实例而不使用New运算符。

我能想到的唯一选择是欺骗TS编译器,并将返回类型指定为void,然后在变量中使用type 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()而不是new运算符:

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

答案 1 :(得分:0)

我怀疑您遇到了我遇到的相同问题(把我带到了这里)。

我试图为现有的纯JavaScript(.d.ts)项目添加一些TypeScript类型定义(.js)。

JavaScript源是传统的constructor函数(具有原型类方法),该函数检测是否在没有new的情况下调用了该函数,并做了正确的事情:

const MyObject = function (options) {
    if (!(this instanceof MyObject)) {
        return new MyObject(options);
    }

    // ...
}

MyObject.prototype.myMethod = function() {
    // Do something...
}

module.exports = MyObject;

我对使用interface添加这种JavaScript对象的TypeScript类型的“正确”方法的理解是:

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;