Ser*_*sky 2 overloading typescript
我有一些接口,它有一个枚举字段。还想为此接口进行重载,这将在某些特定枚举值的情况下再采用一个属性。
举个例子:
enum CellValueType {
DATE,
STRING,
NUMBER
}
export interface TableCell {
type: CellValueType;
value: string; // ...
}
export interface TableCell {
type: CellValueType.DATE;
format: string; // Should be exist only on the DATE type
value: string; // ...
}
Run Code Online (Sandbox Code Playgroud)
但是,问题是使用接口时出现错误:
后续的属性声明必须具有相同的类型。属性“type”必须是“CellValueType”类型,但此处的类型是“CellValueType.DATE”。
错误是可以理解的,没有疑问。
主要问题是如何通过合法途径避免这种情况的发生。
我知道,我可以使用type而不是interface得到这个结构:
export type TableCell = {
type: CellValueType;
value: string;
} | {
type: CellValueType.DATE;
format: string;
value: string;
}
Run Code Online (Sandbox Code Playgroud)
工作得很好,但问题是类无法实现联合类型。
未按预期工作,但DATE仍与第一个签名兼容。为了正确工作,需要将其type: CellValueType更改为type: Exclude<CellValueType, CellValueType.DATE>
另外,我只能为枚举类型创建一个子接口DATE,但也想避免为每种情况创建一个接口。
当您以相同名称定义两个接口时,将执行声明合并。
export interface TableCell {
type: CellValueType;
value: string; // ...
}
export interface TableCell {
type: CellValueType.DATE;
format: string; // Should be exist only on the DATE type
value: string; // ...
}
Run Code Online (Sandbox Code Playgroud)
CellValueType这是您在尝试与合并时遇到的设计行为CellValueType.DATE。引用手册:
如果接口都声明同名但类型不同的非函数成员,编译器将发出错误
现在,当您尝试使用联合来创建所需的类型时,您遇到了另一种设计行为 - 由于 是 的CellValueType.DATE成员CellValueType,因此选择了更广泛的类型(想一想:A | ... | A | B与 相同A | B):
type isInType = CellValueType.DATE extends CellValueType ? true : false; //true;
type isNotInType = CellValueType extends CellValueType.DATE ? true : false; //false;
type cellType = TableCell["type"]; //CellValueType
Run Code Online (Sandbox Code Playgroud)
既然这样,为什么不想创建扩展基本类型的接口呢?这是一个完全有效的抽象策略。看一下下面的例子(注意断言as const,否则 的类型CellValueType.DATE将被扩展为CellValueType):
export enum CellValueType {
DATE,
STRING,
NUMBER
}
interface TableCell {
value: string;
}
export interface DateCell extends TableCell {
type: CellValueType.DATE;
format: string;
}
export interface NumberCell extends TableCell {
//number-specific props here
}
export class DateCell implements DateCell {
format = "yyyy-MM-dd";
type = CellValueType.DATE as const;
value = "2021-02-22";
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6221 次 |
| 最近记录: |