typescript - 如何在 TS 中为具有原型方法的类编写接口?
问题描述
我一直在解决这个问题一段时间,并认为我最终会理解或遇到一个体面的解释。我已经阅读了 TS 手册中的许多文章,google()'d 了它,并搜索了 SO,但还没有找到答案。
我需要知道如何正确、完整地在 TS 类/接口中键入原型方法。
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 中的原型中?
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 {
}
}
如果您遇到需要显式修改原型的特殊情况,那么 typescript 将无法告诉您您在做什么,您需要断言该属性确实已定义。这是通过以下方式完成的!
:
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() {}
推荐阅读
- vue.js - 将特定模块加载为单独的块
- node.js - Lambda 节点 JS Shopify API 调用
- google-apps-script - GAS:“您每天运行服务高级版 gmail 的次数过多” issu
- vb.net - VB.NET:将datagridview中的文本列转换为图像列并根据文本设置图标
- javascript - 无法读取模态弹出窗口上未定义错误的属性“值”
- macros - 尝试在 Verilog 代码的编译时/运行时更改包含语句
- javascript - 包装器不会在 setData 上更新
- mysql - 在Mysql的json类型列vai hibernate中映射Json字符串
- angular-material - 通过角度缩放后拖动svg子
- javascript - “NamedExoticComponent”类型上不存在属性“HEIGHT”
'