如何定义键与对应值类型匹配的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
相关产品推荐
相关产品推荐

