【问题标题】:Type function prototype in typescript打字稿中的类型函数原型
【发布时间】:2020-07-01 22:47:46
【问题描述】:

Typescript:如何使用原型为函数添加类型?

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'.`;

【问题讨论】:

  • 你错过了new吗?
  • 你为什么不使用类呢?

标签: node.js typescript ts-node


【解决方案1】:

如果用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();

【讨论】:

    【解决方案2】:

    更新

    对于 node.js 和 deno,您需要与 undefined 而不是 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
    

    如果你还想用prototype,有什么不推荐的,可以做个hotfix:

    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
    

    【讨论】:

    • 这不是真的。您始终可以使用constructor function 模式。它使用较少,但仍然有效。在typescriptlang.org/docs/handbook/classes.html 中讨论constructor function 的部分。示例中需要的只是new 键盘。
    • 什么不正确?我在哪里说它无效?所有的js都对ts有效,只是方式不对。
    • 是否可以使用 ts-node 运行它,而不是在浏览器中 ``` ts-node "/Users/vaclav.benes/Git/typescript/typescript_samples/learn/proto.ts" /Users/ vaclav.benes/Git/typescript/typescript_samples/learn/proto.ts:17 Fool("Joe").greet(); // Fool 向 Joe 打招呼 ^ TypeError: Fool(...).greet is not a function at Object. (/Users/vaclav.benes/Git/typescript/typescript_samples/learn/proto.ts:17:13) )```
    • 对于浏览器,您需要使用tsc 将.ts 编译为.js,然后您也可以从浏览器运行它,TypeScript 是JavaScript 的类型化超集,可以编译为纯JavaScript。没有编译就无法运行。 ts-node 即时执行。
    • 例如这里typescriptlang.org/play/?target=0#code/…在右侧可以看到TS的JS版本,你可以在浏览器中运行这个JS版本。
    【解决方案3】:

    使用此解决方案,您可以同时使用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()
    );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-17
      • 1970-01-01
      • 2020-07-08
      • 2017-01-29
      • 2019-02-07
      • 2022-01-12
      • 2015-08-10
      相关资源
      最近更新 更多