当前位置: 首页 > 知识库问答 >
问题:

使用枚举键入接口字段的索引签名?

乜承嗣
2023-03-14

我可以用对象类型表示法描述索引类型限制,例如:

enum Enum {
    A = 0,
    B = 1,
}

type EnumMap = {
    [P in Enum]: string;
}

但是,令人惊讶的是,在接口中使用索引表示法时,似乎不可能做到这一点:

enum Enum {
    A = 0,
    B = 1,
}

interface EnumMap {
    [P in Enum]: string;
}

错误是:

计算的属性名称必须是“字符串”、“数字”、“符号”或“任何”类型。

为什么会这样?根据定义,TypeScript中的枚举只能有字符串值或数字值(或两者都有,但不建议这样做),我认为枚举本身对于它列出的所有值都可以像联合类型一样工作。

进一步调查,我还发现,在下面的例子中,< code>EnumValues的类型是< code>number,而不是(我期望的)< code>0 | 1。还是那句话,为什么会这样?

const Enum = {
    A: 0,
    B: 1
};

type EnumKeys = keyof typeof Enum;
type EnumValues = typeof Enum[EnumKeys];

共有1个答案

景胜涝
2023-03-14

关于中的错误:

interface EnumMap {
    [P in Enum]: string;
}

枚举是 TypeScript 中一种特殊的数据结构,它不能分配给字符串|数字|符号。康赛德这个例子:

const key = <T extends string | number | symbol>(t: T) => t

key(Enum) // error

此外,枚举具有特殊行为。

请参见此示例:

const enm = (t: Enum) => t

// Argument of type 'typeof Enum' is not assignable to parameter of type 'Enum'
enm(Enum) // error

所以即使在枚举类型枚举之间也有区别。

让我们回到问题上来。在TS 4.4之前,不允许在接口中使用联合作为索引签名。请考虑这个没有枚举的示例:

interface EnumMap {
    [P in 'a'|'b']: string; // error
}

因此,它是关于TS限制而不是枚举。

至于第二种情况:

const Enum = {
    A: 0,
    B: 1
};

type EnumKeys = keyof typeof Enum;
type EnumValues = typeof Enum[EnumKeys];

这是因为const Enum是可变的。

为了获得 1|0,您应该使其不可变:

const Enum = {
    A: 0,
    B: 1
} as const; // special syntax

type EnumKeys = keyof typeof Enum;
type EnumValues = typeof Enum[EnumKeys]; // 0 | 1
 类似资料:
  • 我有上面的列举 @JsonValue公共字符串getValue(){return value;} 部分和一个示例测试类,如。。。 公开课Foo{ 这个测试类打印出来 @jsonValue在作为map键的枚举字段上使用时不工作。 序列化映射时是否有方法将此枚举用作键? 谢谢

  • 问题内容: 枚举大小写是否可以使用保留关键字? 例如: 在其他语言中,这可以通过以某种方式转义关键字来实现,例如在scala中,我们使用反引号,例如 尽管是保留关键字,但仍可以用作标识符。 迅速有类似的东西吗? 问题答案: 从《 Swift语言指南》(“ 命名常量和变量”部分) 如果需要为常量或变量提供与保留的Swift关键字相同的名称,则在使用该关键字作为名称时,请在关键字前后加上反斜线(`)。

  • 我试图在Avro模式中创建Union字段,并用它发送相应的JSON消息,但要有一个字段-。 https://avro.apache.org/docs/1.8.2/spec.html#工会 具有相应JSON数据的最简单联合类型(avro模式)的示例是什么?(尝试制作不含NULL/空数据的示例和含NULL/空数据的示例)。

  • 我想映射2个模型,其中每个模型都有几乎相同的枚举。让我展示: 第一个模型有枚举: 第二个模型具有枚举: 我有这样的自定义映射方法: 然后我用: 但是你可以得到: 我还创建了枚举映射器,如: 但我不需要单独设置,只希望枚举字段映射到内部映射中。简单地说,当我做枚举时,也应该映射。 谢谢 p、 对不起我的英语,希望我的问题有意义:)

  • 我正在使用Compass从DTO对象中过滤数据。如果字段是POJO对象,则使用标记字段;如果字段是字符串,则使用标记字段。这非常有效:我将对象和字符串编入索引。 我的问题是如何注释枚举数据类型? 我拥有的枚举示例: 在这个片段中,我应该在哪里放置注释,应该放置哪个注释?