使用枚举键入接口字段的索引签名?
Posted
技术标签:
【中文标题】使用枚举键入接口字段的索引签名?【英文标题】:Use an enum to type an index signature of an interface field? 【发布时间】:2019-04-29 17:27:04 【问题描述】:我可以用如下的对象类型表示法来描述索引类型限制:
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 中的枚举只能有字符串或数字值(甚至两者都有,但不推荐这样做),我认为枚举本身对于它列出的所有值都可以像联合类型一样工作。
进一步调查,我还发现,在以下示例中,EnumValues
的类型为 number
,而不是(我期望的)0 | 1
。再说一遍,为什么会这样?
const Enum =
A: 0,
B: 1
;
type EnumKeys = keyof typeof Enum;
type EnumValues = typeof Enum[EnumKeys];
【问题讨论】:
我相信这些答案会对您有所帮助:***.com/questions/64970414/… 和 ***.com/questions/37233735/… 【参考方案1】:关于错误:
interface EnumMap
[P in Enum]: string;
枚举是 TypeScript 中的一种特殊数据结构,它不能分配给 string | number | symbol
。
考虑这个例子:
const key = <T extends string | number | symbol>(t: T) => t
key(Enum) // error
另外,enum
有特殊行为。
看这个例子:
const enm = (t: Enum) => t
// Argument of type 'typeof Enum' is not assignable to parameter of type 'Enum'
enm(Enum) // error
所以即使Enum
和typeof Enum
之间也存在差异。
让我们回到我们的问题。
在TS 4.4 之前,您不得在接口中使用联合作为索引签名。
考虑这个没有enum
的例子:
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
【讨论】:
以上是关于使用枚举键入接口字段的索引签名?的主要内容,如果未能解决你的问题,请参考以下文章