将枚举用作字典键

问题描述 投票:4回答:2

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

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

enum Direction {
    Up,
    Down,
}

const lookup: EnumDictionary<Direction, number> = {
    [Direction.Up]: 1,
    [Direction.Down]: -1,
};

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

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

这似乎让我感到很奇怪,因为这是说lookup的类型应该是Direction而不是EnumDictionary<Direction, number>。我可以通过将lookup声明更改为:

来确认这一点。
const lookup: EnumDictionary<Direction, number> = Direction.Up;

并且没有错误。

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

TypeScript版本:3.2.1

typescript dictionary enums
2个回答
8
投票

您可以执行以下操作:

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
};

我感到惊讶,直到我意识到枚举可以被认为是specialised union type

另一个变化是,枚举类型本身有效地变成了每个枚举成员的并集。虽然我们尚未讨论联合类型,您需要知道的是,对于联合枚举,类型系统为能够利用这样的事实:它知道一组确切的值存在于枚举本身中。

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

Record

0
投票
type Record<K extends string, T> = {
    [P in K]: T;
}

因此,如果您需要所有的Enum值

enum FunStuff {
  PARTY = "party",
  CAKE = "cake",
  PIZZA = "pizza",
}

然后,如果您只想要枚举中的值,但可以添加任意数量的值,则可以添加?

type MapOfFunStuff = {
  counts: { [key in FunStuff] : number };
}
© www.soinside.com 2019 - 2024. All rights reserved.