在Typecript中使用Enum作为受限密钥类型

Hiv*_*aga 13 typescript

问题是可以枚举用作键类型而不仅仅是"数字"或"字符串"?目前似乎唯一可能的声明是x:{[key:number]:any}其中key可以是"number"或"string"类型.有可能在这个例子中做出类似的东西:

例:

enum MyEnum
{
    First,
    Second
}

var layer:{[key:MyEnum]:any};
Run Code Online (Sandbox Code Playgroud)

Aid*_*din 54

简答:

let layer: Partial<Record<MyEnum, any>>;
Run Code Online (Sandbox Code Playgroud)

长答案(附详细信息):

我有同样的问题。我想让以下代码工作。

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

Run Code Online (Sandbox Code Playgroud)

从关于这个问题的另一个答案开始,我得到了:

type myType = {[key in keyof typeof MyEnum]: number};
Run Code Online (Sandbox Code Playgroud)

但它会唠叨o is missing "yyy"。所以我需要告诉它对象将有一些枚举键,而不是全部。所以我必须添加?以获得:

type myType = {[key in keyof typeof MyEnum]?: number};
Run Code Online (Sandbox Code Playgroud)

它工作正常,直到我在代码末尾添加了一行以在第一次创建后修改对象。现在它抱怨通过继承的类型keyof具有它的属性,readonly并且在第一次创建后我无法触摸它们!:| 实际上,将鼠标悬停myTypeTypescript Playground 上,它会显示为:

type myType = {
    readonly xxx?: number | undefined;
    readonly yyy?: number | undefined;
    readonly zzz?: number | undefined;
}
Run Code Online (Sandbox Code Playgroud)

现在,为了删除不需要的readonly,我发现我可以使用:

type myType = {-readonly [key in keyof typeof myEnum1]?: number };
Run Code Online (Sandbox Code Playgroud)

很丑,但工作

直到我玩了 Typescript Utility Types,并找到了我想要的东西!

type myType = Partial<Record<MyEnum, number>>;
Run Code Online (Sandbox Code Playgroud)

:)


Hug*_*sen 54

自 2018 年以来,Typescript 中有一种更简单的方法,无需使用keyof typeof

let layer: { [key in MyEnum]: any}
Run Code Online (Sandbox Code Playgroud)

不必包含所有键:

let layer: { [key in MyEnum]?: any}
Run Code Online (Sandbox Code Playgroud)

  • “不必包含所有键:” -&gt; 正是我正在寻找的 (4认同)
  • Keyof typeof 不等于 enum 中的 key,它创建的类型实际上由 enum 的键组成,而不是值 (4认同)
  • 看起来效果很好。当使用“typeof”时,看起来我的对象中的键是从枚举的键创建的,而不是该键的值。 (2认同)

Seb*_*ian 26

是.只需输入

let layer:{[key in keyof typeof MyEnum]: any}
Run Code Online (Sandbox Code Playgroud)

keyof从Typescript 2.1开始,该关键字可用.有关更多详细信息,请参阅TypeScript文档.仅keyof用于枚举不起作用(您将获得该enum类型的键而不是枚举常量),因此您必须键入keyof typeof.

  • 如果您不希望强制包含所有枚举值,您可以执行 `{[key in keyof typeof MyEnum]?: any}` (`?` 可以缺少一些枚举,很好。) (7认同)
  • 请参阅下面 Hugo Elhaj-Lahsen 的回答。这个答案现在可能实际上已经过时了! (2认同)

Ale*_*mes 7

对于那些正在寻找获得 thekeys的方法enum而不是 its 的人value,您只需要更改以下内容:

type myType = Partial<Record<MyEnum, number>>;
Run Code Online (Sandbox Code Playgroud)

对此:

type myType = Partial<Record<keyof typeof MyEnum, number>>;
Run Code Online (Sandbox Code Playgroud)


Sh *_*eeb 6

实际上它对我有用,没有任何解决方法。

以下是一些案例:

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}
Run Code Online (Sandbox Code Playgroud)

值得注意的是,“z1”的情况即使运行良好,但您以后无法修改它,因为它是只读的。您可以使用关键字-readonly来删除此限制。

x1.a=2 
x3.a=2
z1.a=2 //error: read only
Run Code Online (Sandbox Code Playgroud)

我创建了一个打字稿游乐场来亲自查看不同案例的问题