简体   繁体   English

在 Typescript 中使用 Enum 作为受限键类型

[英]Use Enum as restricted key type in Typescript

The question is can enum be used as a key type instead of only "number" or "string" ?问题是枚举可以用作键类型,而不仅仅是“数字”或“字符串”? Currently it seems like the only possible declaration is x:{[key:number]:any} where key can be of type "number" or "string".目前似乎唯一可能的声明是 x:{[key:number]:any} ,其中键可以是“数字”或“字符串”类型。 Is it possible to make something like in this example:是否可以在此示例中制作类似的东西:

Example:示例:

enum MyEnum
{
    First,
    Second
}

var layer:{[key:MyEnum]:any};

Yes.是的。 Just type只需输入

let layer:{[key in keyof typeof MyEnum]: any}

The keyof keyword is available since Typescript 2.1. keyof关键字从 Typescript 2.1 开始可用。 See the TypeScript documentation for more details.有关更多详细信息,请参阅TypeScript 文档 Using only keyof for enums wouldn't work (you'd get the keys of the enum type and not the enum constants), so you have to type keyof typeof .仅将keyof用于枚举是行不通的(您将获得enum类型的键而不是枚举常量),因此您必须键入keyof typeof

Short Answer:简答:

let layer: Partial<Record<MyEnum, any>>;

Long Answer (with details):长答案(附详细信息):

I had the same problem.我有同样的问题。 I wanted to have the following piece of code work.我想让以下代码工作。

enum MyEnum {
    xxx = "xxx",
    yyy = "yyy",
    zzz = "zzz",
}

type myType = ...; // Fill here

const o: myType = { // keys should be in MyEnum, values: number
   [MyEnum.xxx]: 2,
   "hi": 5, // <--- Error: complain on this one, as "hi" is not in enum
}

o[MyEnum.yyy] = 8; // Allow it to be modified later

Starting from the other answer on this question, I got to:从关于这个问题的另一个答案开始,我得到了:

type myType = {[key in keyof typeof MyEnum]: number};

But it would nag that o is missing "yyy" .但它会唠叨o is missing "yyy" So I needed to tell it that the object is going to have some of the enum keys, not all of them.所以我需要告诉它对象将有一些枚举键,而不是全部。 So I got to add ?所以我要补充? to get:得到:

type myType = {[key in keyof typeof MyEnum]?: number};

It was working fine, until I added the line at the end of the code to modify the object after its first creation.它工作正常,直到我在代码末尾添加了一行以在第一次创建后修改对象。 Now it was complaining that the type inherited through keyof has its properties as readonly and I cannot touch them after the first creation!现在它抱怨通过keyof继承的类型具有readonly属性,并且在第一次创建后我无法触摸它们! :| :| In fact, hovering over myType in Typescript Playground , it will be shown as:事实上,在徘徊myType打字稿游乐场,它会显示为:

type myType = {
    readonly xxx?: number | undefined;
    readonly yyy?: number | undefined;
    readonly zzz?: number | undefined;
}

Now, to remove that unwanted readonly , I found that I can use:现在,要删除不需要的readonly ,我发现我可以使用:

type myType = {-readonly [key in keyof typeof myEnum1]?: number };

Quite ugly, but working !很丑,但工作

Until I played with Typescript Utility Types , and found what I wanted!直到我玩了 Typescript Utility Types ,并找到了我想要的东西!

type myType = Partial<Record<MyEnum, number>>;

:) :)

Since 2018 , there is an easier way in Typescript, without using keyof typeof :自 2018 年以来,Typescript 中有一种更简单的方法,无需使用keyof typeof

let layer: { [key in MyEnum]: any}

To not have to include all keys:不必包含所有键:

let layer: { [key in MyEnum]?: any}

For those who are seeking for a way to get the keys of the enum instead its value , you just need to change from this:对于那些正在寻找一种方法来获取enumkeys而不是它的value ,你只需要从这里改变:

type myType = Partial<Record<MyEnum, number>>;

to that:对此:

type myType = Partial<Record<keyof typeof MyEnum, number>>;

actually it worked with me without any workaround.实际上它在没有任何解决方法的情况下对我有用。

here is some cases:这是一些情况:

enum EnumString {
  a="a",
  b="b"
}

enum EnumNum {
  a,
  b
}

type Type = "a" | "b"


let x1:{[k in EnumString]?:any }={a:1} //working
let x2:{[k in EnumNum]?:any }={a:1} //error: Type '{ a: number; }' is not assignable to type '{ 0?: any; 1?: any; }'
let x3:{[k in Type]?:any }={a:1} //working; defining a union type is easer than defining an enum string 

let y1:{[k: EnumString]?:any }={a:1}
let y2:{[k: EnumNum]?:any }={a:1}
let y3:{[k in Type]?:any }={a:1}

let z1:{[k in keyof typeof EnumString]?:any }={a:1}
let z2:{[k in keyof typeof EnumNum]?:any }={a:1}
let z3:{[k: keyof typeof Type]?:any }={a:1}

it is important to note that the case "z1", even it works well, but you cannot modify it later as it is a read only.重要的是要注意案例“z1”,即使它运行良好,但您以后无法修改它,因为它是只读的。 you can use the keyword -readonly to remove this constraint.您可以使用关键字-readonly删除此约束。

x1.a=2 
x3.a=2
z1.a=2 //error: read only

I created a typescript playground to see issues of different cases yourself我创建了一个打字稿游乐场来自己查看不同案例的问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM