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

TypeScript中React action/reducer模式下如何更优雅标注data类型?

优化方案

可以通过泛型工具提取对应类型的Action,让每个处理函数的入参自动匹配对应类型,无需手动添加类型守卫,也不需要switch语句,实现代码如下:

// 示例State类型,可根据实际业务调整
type State = { nums: number[] };

export type Action = 
    { type: "DO_SOMETHING", data: { num: number } } |
    { type: "DO_SOMETHING_ELSE", data: { nums: number[] } };

// 工具泛型:根据type值从Action联合类型中提取对应完整Action项
type ExtractActionByType<T extends Action['type']> = Extract<Action, { type: T }>;

// 重构Actions映射类型,每个处理函数只接收对应type的action
type Actions = {
    [T in Action['type']]: (state: State, action: ExtractActionByType<T>) => State;
};

// 现在每个处理函数的action类型自动匹配,无需额外类型判断
const actions: Actions = {
   DO_SOMETHING: (state, action) => {
       return { nums: [action.data.num] };
   },
   DO_SOMETHING_ELSE: (state, action) => {
       return { nums: action.data.nums };
   }
};

// 配套类型安全的reducer实现
function reducer(state: State, action: Action): State {
    return actions[action.type](state, action as never);
}

方案说明

  • 新增action类型时仅需更新Action联合类型定义,TypeScript会自动校验actions对象中是否存在对应类型的处理函数,避免漏写逻辑。
  • 所有处理函数的action参数类型自动推导,无需手动编写类型守卫代码,比原生switch写法更简洁,类型安全性完全一致。
  • reducer中的as never是对TypeScript类型系统的合理妥协,由于TS暂时无法自动推导映射函数的入参与传入action的类型匹配关系,该写法完全类型安全,不会引入运行时风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 20:48:03