将枚举映射到键值(使用泛型)

mapping enum to a key value (with generics)

假设我有一个简单的枚举

enum MyEnum {
  a,
  b,
  c
}

将枚举映射到键值常量很简单:

type A<V> = { [k in MyEnum]: V };

const testA: A<string> = { 
  [MyEnum.a]: '',
  [MyEnum.b]: '',
  [MyEnum.c]: ''
};

当我尝试将枚举作为通用类型传递时,问题开始了:

type B1<T, V> = { [k in T]: V } // that won't work
const testB: A<MyEnum , string> = { ... } // usage

我尝试了几种方法ideas in this play-ground

有一些类似的问题(如下所列),但我仍然觉得在这个特定示例中,如果第一个选项 (type A<V> = { [k in MyEnum]: V };) 是可能的,那么其他选项也应该是 (type B1<T, V> = ).

Mapping Enum to Type of keys or values

is-it-possible-to-allow-literal-string-values-with-typescripts-enum-type

type B1<T, V> = { [k in T]: V } 上的错误消息显示 Type 'T' is not assignable to type 'string | number | symbol'.,可以通过向 T 添加约束来补救:

type B<T extends PropertyKey, V> = { [k in T]: V }

(使用 built-in type PropertyKey = string | number | symbol

现在您可以将枚举作为通用参数传递给 B

const testB: B<MyEnum, string> = {
  [MyEnum.a]: 'aa',
  [MyEnum.b]: 'bb',
  [MyEnum.c]: 'cc'
};

TypeScript playground

或者,正如 Alex Wayne 所建议的,您可以完全放弃声明 B,而只使用 built-in Record 类型。它的定义是

type Record<K extends keyof any, T> = {[P in K]: T}

相当于B,因为keyof anystring | number | symbol,就像PropertyKey.