You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在TypeScript中声明键值匹配的对象区分类型

解决方案

这是个很典型的TypeScript类型细化需求,原来的Record<EventType, MyEvent[]>会让每个属性都接受所有MyEvent类型的元素,没法做到按键区分对应的值类型。我们可以通过映射类型+内置条件类型来实现精准的类型约束:

步骤1:定义提取对应事件类型的工具类型

首先我们需要一个工具类型,用来根据EventType枚举值,从MyEvent联合类型里筛选出对应的具体事件元组:

type ExtractEventByType<T extends EventType> = Extract<MyEvent, [T, ...any[]]>;

这里用到了TypeScript内置的Extract工具类型,它的作用是从联合类型中提取出符合指定条件的子类型。我们的条件是“元组的第一个元素等于目标EventType值”,通过[T, ...any[]]匹配任意以T开头的元组。

步骤2:生成精准的分组对象类型

接下来用映射类型遍历EventType的所有枚举值,为每个键生成对应的事件数组类型:

type EventsGrouped = {
  [K in EventType]: ExtractEventByType<K>[];
};

这个类型会为每个EventType枚举值K,生成一个值类型为ExtractEventByType<K>[]的属性——也就是只包含对应类型事件的数组。

步骤3:应用类型到对象

最后把eventsGrouped的类型替换成我们定义好的EventsGrouped:

enum EventType { A, B, C };

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

type ExtractEventByType<T extends EventType> = Extract<MyEvent, [T, ...any[]]>;

type EventsGrouped = {
  [K in EventType]: ExtractEventByType<K>[];
};

const eventsGrouped: EventsGrouped = {
  [EventType.A]: [],
  [EventType.B]: [],
  [EventType.C]: [],
};

验证类型约束

现在你可以测试一下,TypeScript会严格约束每个数组的元素类型:

// ✅ 合法:EventType.A对应的事件类型是[EventType.A, number]
eventsGrouped[EventType.A].push([EventType.A, 42]);

// ❌ 非法:EventType.A的数组不能接受EventType.B的事件,会触发类型报错
eventsGrouped[EventType.A].push([EventType.B, "test"]);

// ✅ 合法:EventType.C对应的事件类型是[EventType.C, number, string]
eventsGrouped[EventType.C].push([EventType.C, 100, "hello"]);

内容的提问来源于stack exchange,提问作者forsen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 10:25:46