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

如何定义键与对应值类型匹配的TypeScript Action映射?

实现类型安全的Action映射

你想要的其实是让映射的每个键(即Action的type值)对应仅该type的具体Action类型,而不是整个Action联合。用TypeScript的Extract工具类型配合映射类型就能轻松解决这个问题,不需要复杂的自定义分布式条件类型(不过Extract本身就利用了分布式条件类型的特性)。

第一步:先明确你的Action联合类型(示例)

假设你的Action类型是这样的:

type Action =
  | { type: "fulfil"; payload: string }
  | { type: "snooze"; delay: number }
  | { type: "cancel"; reason: string };

第二步:定义类型安全的映射类型

替换你原来的宽松定义,用Extract来关联键和对应的值类型:

type ActionMap = {
  // 对每个Action的type值T,值类型是Action中type为T的具体类型
  [T in Action['type']]?: Extract<Action, { type: T }>;
};

// 初始化映射
const lastAction: ActionMap = {};

第三步:验证类型约束

现在如果尝试把类型不匹配的Action赋值给错误的键,TypeScript会直接抛出编译错误:

// 创建一个type为"snooze"的Action
const snoozeAction = { type: "snooze", delay: 5 } satisfies Action;

// 错误:类型"{ type: "snooze"; delay: number; }"不能赋值给类型"{ type: "fulfil"; payload: string; } | undefined"
lastAction["fulfil"] = snoozeAction;

而正确的赋值则完全没问题:

// 正常通过编译
lastAction["snooze"] = snoozeAction;
lastAction["fulfil"] = { type: "fulfil", payload: "Done!" };

原理说明

Extract<Union, Type>是TypeScript内置的工具类型,它会从联合类型Union中提取出所有可赋值给Type的成员。在这里,对于每个T(即Action的某个type值),Extract<Action, { type: T }>会精准定位到Action联合中那个type属性等于T的具体类型,从而实现键与值的类型强绑定。

如果你不想单独定义ActionMap类型,也可以直接把类型写在变量声明里:

const lastAction: { [T in Action['type']]?: Extract<Action, { type: T }> } = {};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:11:12