typescript 声明对象的类型,其中对象的键区分值类型和数组联合

1zmg4dgp  于 2023-01-21  发布在  TypeScript
关注(0)|答案(1)|浏览(138)

我认为,最好用一个明确的例子来说明这一点:

enum EventType { A, B, C };

type MyEvent =
  [EventType.A, number] |
  [EventType.B, string] |
  [EventType.C, number, string];

const eventsGrouped: Record<EventType, MyEvent[]> = {
  [EventType.A]: [],
  [EventType.B]: [],
  [EventType.C]: [],
};

目标是为eventsGrouped对象创建一个类型,该类型基于键区分值类型
在伪代码中:

Record<EventType, MyEvent where MyEvent[0] === object entry key>

因此:

  • eventsGrouped[EventType.A]的类型为[EventType.A, number]
  • eventsGrouped[EventType.B]的类型为[EventType.B, string]
  • eventsGrouped[EventType.C]的类型为[EventType.C, number, string]
rekjcdws

rekjcdws1#

4.1版中引入的键重Map非常简单:

type EventsGrouped = { [T in MyEvent as T[0]]: T };

一开始有点难以理解,但是我们在联合体上“循环”,对于联合体的每个成员,我们使用T[0]作为 key,使用T作为 value
然后可以将其用作eventsGrouped的类型:

const eventsGrouped: EventsGrouped = {

Playground
在4.1之前,仍然可以使用Map类型!它需要额外的工作,因为你需要手动提取相应的成员:

type EventsGrouped = { [K in MyEvent[0]]: Extract<MyEvent, [K, ...any[]]> };

Playground

相关问题