gpt4 book ai didi

typescript - 如何通过接口(interface)避免 `Subsequent property declarations must have the same type`

转载 作者:行者123 更新时间:2023-12-02 02:21:50 25 4
gpt4 key购买 nike

我有一些接口(interface),它有一个枚举字段。还想为此接口(interface)进行重载,这将在某些特定枚举值的情况下再采用一个属性。

举个例子:

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; // ...
}

但是,问题是使用接口(interface)时出现错误:

Subsequent property declarations must have the same type. Property 'type' must be of type 'CellValueType', but here has type 'CellValueType.DATE'.

错误是可以理解的,没有疑问。

主要问题是如何通过合法的方式避免这种情况。

我知道,我可以使用 type而不是interface并得到这个结构:

export type TableCell = {
type: CellValueType;
value: string;
} | {
type: CellValueType.DATE;
format: string;
value: string;
}

工作得很好,但问题是类无法实现联合类型。


未按预期工作,DATE仍然与第一个签名兼容。为了正常工作,它需要 type: CellValueType更改为type: Exclude<CellValueType, CellValueType.DATE>

此外,我只能为 DATE 创建子接口(interface)枚举类型,但也希望避免为每种情况创建接口(interface)。

最佳答案

当您在同一名称下定义两个接口(interface)时,declaration merge已执行。

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; // ...
}

这是您在尝试将 CellValueTypeCellValueType.DATE 合并时遇到的设计行为。引用the handbook :

The compiler will issue an error if the interfaces both declare a non-function member of the same name, but of different types

现在,当您尝试使用联合来创建所需的类型时,您遇到了另一种设计行为 - 因为 CellValueType.DATECellValueType 的成员,选择更宽的类型(想一想:A | ... | A | BA | B 相同):

type isInType = CellValueType.DATE extends CellValueType ? true : false; //true;
type isNotInType = CellValueType extends CellValueType.DATE ? true : false; //false;
type cellType = TableCell["type"]; //CellValueType

既然如此,您为什么不想创建扩展基本类型的接口(interface)呢?这是一个完全有效的抽象策略。看一下下面的示例(请注意 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";
}

Playground

关于typescript - 如何通过接口(interface)避免 `Subsequent property declarations must have the same type`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66309774/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com