3

打字稿:如何为带有原型的函数添加类型?

interface Fool {
  greet(): any;
}

function Fool(name: string) {
  this.name = name;
}

Fool.prototype.greet = function() {
  console.log(`Fool greets ${this.name}`);
};

Fool('Joe').greet();
`Property 'greet' does not exist on type 'void'.`;
4

3 回答 3

3

new如果用西装构造实例:

interface Fool {
  name: string;
  greet(): void;
}

interface FoolConstructor {
  new (name: string): Fool;
  (): void;
}

const Fool = function(this: Fool, name: string) {
  this.name = name;
} as FoolConstructor;

Fool.prototype.greet = function() {
  console.log(`Fool greets ${this.name}`);
};

new Fool('Joe').greet();
于 2020-07-01T12:06:36.437 回答
1

使用此解决方案,您可以同时使用Fool(name)new Fool(name)

interface Fool {
  name: string;
  greet(): void;
}

interface FoolConstructor {
  new(name: string): Fool;
  (name: string): Fool;
}

const Fool = function (this: Fool | void, name: string): Fool {
  if (!(this instanceof Fool)) {
    return new Fool(name);
  }

  this.name = name;
  return this;
} as FoolConstructor;

Fool.prototype.greet = function(this: Fool) {
  console.log(`Fool greets ${this.name}`);
};

console.log(
  new Fool('Joe').greet(),
  Fool('Joe').greet()
);
于 2020-07-01T14:47:46.810 回答
1

更新

在 node.js 和 deno 的情况下,您需要比较 withundefined而不是Window

interface Fool {
    greet(): any;
}


function Fool(this: any, name: string): Fool {
    if (this === undefined) { // check if it was called statically.
        return new (Fool as any)(name);
    }
    this.name = name;
    return this;
}

Fool.prototype.greet = function () {
    console.log(`Fool greets ${this.name}`);
};

Fool("Joe").greet(); // Fool greets Joe

原来的

TS 中的正确方法是使用类而不是prototype. 那么你不需要解决这个问题。

class Fool {
  constructor(public name: string) {}

  greet() {
      console.log(`Fool greets ${this.name}`);
  }  
}

new Fool("Joe").greet(); // Fool greets Joe

如果你仍然想使用原型,不推荐的,你可以做一个修补程序:

interface Fool {
  greet(): any;
}


function Fool(this: any, name: string): Fool {
  if (this.constructor === Window) { // check if it was called statically.
    return new (Fool as any)(name);
  }
  this.name = name;
  return this;
}

Fool.prototype.greet = function () {
  console.log(`Fool greets ${this.name}`);
};

Fool("Joe").greet(); // Fool greets Joe
于 2020-05-18T14:20:06.383 回答