使用枚举作为字典键

Mik*_*uck 6 enums dictionary typescript

我正在尝试为给定的枚举创建保证的查找。与之类似,对于枚举的每个键,在查找中应该只存在一个值。我想通过类型系统来保证这一点,以便在枚举扩展时不会忘记更新查找。我尝试了这个:

type EnumDictionary<T, U> = {
    [K in keyof T]: U;
};

enum Direction {
    Up,
    Down,
}

const lookup: EnumDictionary<Direction, number> = {
    [Direction.Up]: 1,
    [Direction.Down]: -1,
};
Run Code Online (Sandbox Code Playgroud)

但是我收到这个奇怪的错误:

输入'{[Direction.Up]:数字;[Direction.Down]:数字;}”不可分配给“方向”类型。

在我看来这很奇怪,因为它说的类型lookup应该是Direction而不是EnumDictionary<Direction, number>。我可以通过将lookup声明更改为以下内容来确认这一点:

const lookup: EnumDictionary<Direction, number> = Direction.Up;
Run Code Online (Sandbox Code Playgroud)

而且没有错误。

如何为枚举创建查找类型,以确保枚举的每个值都将导致其他类型的值?

TypeScript版本:3.2.1

rhi*_*don 18

TypeScript 2.9 开始,您可以使用语法{ [P in K]: XXX }

所以对于下面的枚举

enum Direction {
    Up,
    Down,
}
Run Code Online (Sandbox Code Playgroud)

如果您希望需要所有 Enum 值,请执行以下操作:

const directionDictAll: { [key in Direction] : number } = {
    [Direction.Up]: 1,
    [Direction.Down]: -1,
}
Run Code Online (Sandbox Code Playgroud)

或者,如果您只想要枚举中的值,但可以添加任意数量的值,?如下所示:

const directionDictPartial: { [key in Direction]? : number } = {
    [Direction.Up]: 1,
}
Run Code Online (Sandbox Code Playgroud)

  • 我不知道?窍门,谢谢分享! (2认同)

mie*_*sol 10

您可以按照以下步骤进行操作:

type EnumDictionary<T extends string | symbol | number, U> = {
    [K in T]: U;
};

enum Direction {
    Up,
    Down,
}

const a: EnumDictionary<Direction, number> = {
    [Direction.Up]: 1,
    [Direction.Down]: -1
};
Run Code Online (Sandbox Code Playgroud)

直到我意识到枚举可以看作是一种特殊的联合类型,我才感到惊讶。

另一个变化是枚举类型本身可以有效地成为每个枚举成员的并集。尽管我们还没有讨论联合类型,但是您只需要知道联合枚举,类型系统就可以利用这样的事实,即它知道枚举本身中存在的确切值集。

这种EnumDictionary定义的方法基本上是内置Record类型:

type Record<K extends string, T> = {
    [P in K]: T;
}
Run Code Online (Sandbox Code Playgroud)

  • 好的!我还建议如果可能的话使用字符串值,否则一旦添加新的枚举成员,您会收到奇怪的错误消息,例如“property 2 is Missing in ...” (2认同)
  • @TorbenRahbekKoch 我这样声明它: type Dictionary&lt;TKey extends string | 符号| 数字,TValue&gt; = Partial&lt;Record&lt;TKey, TValue&gt;&gt;; (2认同)