【问题标题】:How do I write an interface for a class with prototype methods in TS?如何在 TS 中为具有原型方法的类编写接口?
【发布时间】:2021-01-23 22:43:00
【问题描述】:

我一直在解决这个问题一段时间,并认为我最终会理解或遇到一个体面的解释。我已经阅读了 TS 手册中的许多文章,google() 了它,并搜索了 SO,但还没有找到答案。

我需要知道如何在 TS 类/接口中正确且完整地键入 prototype 方法。

interface UploadFileInterface {
    contentSizes: number[];
    chunks: [];
    chunksDone: number;
    getChunkLength: (id: number) => void;
    name: string;
    size: string;
    chunksQuantity: number;

}

class UploadedFile implements UploadFileInterface {

    contentSizes: Array<number> = [];
    chunks: [] = [];
    chunksDone: number = 0;
    getChunkLength: (id: number) => void;
     ^^^^^^^^ - 'Property 'getChunkLength' has no initializer and is not definitely assigned in the constructor.'

    constructor(
        public name: string, 
        public size: string, 
        public chunksQuantity: number
        ) {}

}

UploadedFile.prototype.getChunkLength = function(id: number): void {
    
}

我得到了这个可怕的“属性 'getChunkLength' 没有初始化器,并且没有在构造函数中明确分配。”错误。

我试图将 getChunkLength 完全从类和接口中移出,并保留它在原型上的编写方式(因为接口应该只描述类的“实例端”),但随后错误移动了到原型上的函数:

interface UploadFileInterface {
    contentSizes: number[];
    chunks: [];
    chunksDone: number;
    //getChunkLength: (id: number) => void;
    name: string;
    size: string;
    chunksQuantity: number;

}

class UploadedFile implements UploadFileInterface {

    contentSizes: Array<number> = [];
    chunks: [] = [];
    chunksDone: number = 0;
    //getChunkLength: (id: number) => void;

    constructor(
        public name: string, 
        public size: string, 
        public chunksQuantity: number
        ) {}

}

UploadedFile.prototype.getChunkLength = function(id: number): void {
    
}

我觉得很奇怪,我似乎找不到更多关于这个场景的线索,就像手册中很明显或直接解释的东西一样,但我似乎找不到。你不应该直接在 TS 的原型中添加东西吗?我什至尝试在构造函数中使用 Object.setPrototypeOf() 来查看它是否会接受它,但没有运气。

我做错了什么?我应该只在 TS 中使用类并将方法直接放在类上吗?如果是这样,工厂函数如何适应 TS?有人可以告诉我解决这些情况的不同技巧吗?

TS Playground

【问题讨论】:

    标签: typescript class methods prototype factory


    【解决方案1】:

    难道你不应该直接在 TS 中的原型中添加东西吗?

    Typescript 希望您使用类语法来定义您的类。这种语法可能没有明确提到原型,但功能仍然被添加到原型中。

    所以下面的例子会在原型中添加一个getChunkLength函数:

    class UploadedFile implements UploadFileInterface {
        contentSizes: Array<number> = [];
        chunks: [] = [];
        chunksDone: number = 0;
    
        constructor(
            public name: string, 
            public size: string, 
            public chunksQuantity: number
        ) {}
    
        getChunkLength(id: string): void {
        
        }
    }
    

    如果您有一个不寻常的情况需要显式修改原型,那么打字稿将无法告诉您在做什么,您需要断言该属性确实已定义。这是通过! 完成的:

    class UploadedFile implements UploadFileInterface {
    
        contentSizes: Array<number> = [];
        chunks: [] = [];
        chunksDone: number = 0;
        getChunkLength!: (id: number) => void;
    
        // ... constructor omitted
    }
    
    UploadedFile.prototype.getChunkLength = function(id: number): void {
        
    }
    

    工厂函数如何适应 TS?

    您可以使用类上的静态函数来做到这一点:

    class Example () {
      public static createInstance() {
        return new Example();
      }
    
      private constructor() {}
    }
    
    // used like:
    const example1 = Example.createInstance();
    

    或者,如果您不需要将构造函数保持私有,您可以让工厂成为类外部的辅助函数:

    const createInstance = () => new Example();
    
    class Example() {}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-09
      • 2011-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多