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

为合并动作处理对象的Reducer编写正确的TypeScript类型

解决方案

要实现将拆分的动作处理函数合并后直接调用,核心是让TypeScript正确关联动作类型与对应处理函数的参数类型,以下是完整的类型定义和实现步骤:

1. 定义状态与动作类型

首先明确全局状态和所有动作的联合类型,确保每个动作包含唯一type和对应结构的payload:

type State = { count: number; name: string };

// 单个动作类型
type IncrementAction = { type: 'INCREMENT'; payload: { amount: number } };
type DecrementAction = { type: 'DECREMENT'; payload: { amount: number } };
type SetNameAction = { type: 'SET_NAME'; payload: { newName: string } };

// 所有动作的联合类型
type AllActions = IncrementAction | DecrementAction | SetNameAction;

2. 定义动作处理映射类型

创建通用映射类型,将每个动作的type映射为对应的处理函数,确保函数参数的payload类型与动作严格匹配:

type ActionHandlerMap<StateType, ActionType extends { type: string; payload: unknown }> = {
  [ActionKey in ActionType['type']]: (
    state: StateType,
    payload: Extract<ActionType, { type: ActionKey }>['payload']
  ) => StateType;
};

3. 拆分定义动作处理函数

按照业务模块拆分处理函数,每个模块的处理函数都遵循上面定义的映射类型:

// 计数相关处理
const countHandlers: ActionHandlerMap<State, IncrementAction | DecrementAction> = {
  INCREMENT: (state, payload) => ({ ...state, count: state.count + payload.amount }),
  DECREMENT: (state, payload) => ({ ...state, count: state.count - payload.amount }),
};

// 名称相关处理
const nameHandlers: ActionHandlerMap<State, SetNameAction> = {
  SET_NAME: (state, payload) => ({ ...state, name: payload.newName }),
};

4. 合并处理函数并实现Reducer

合并处理函数时,通过类型断言让TypeScript识别合并后的完整映射关系;Reducer中直接通过action.type调用对应处理函数,同时增加默认分支处理未知动作:

const allHandlers = {
  ...countHandlers,
  ...nameHandlers,
} as ActionHandlerMap<State, AllActions>;

function reducer(state: State, action: AllActions): State {
  const handler = allHandlers[action.type];
  return handler ? handler(state, action.payload) : state;
}

关键说明

  • ActionHandlerMap通过Extract工具类型,从动作联合类型中精准提取对应type的payload类型,避免类型宽泛化。
  • 合并处理函数时的类型断言是必要的,因为TypeScript默认会将合并后的对象类型推断为交叉类型,丢失type与payload的关联关系。
  • 增加默认分支可以避免因未知动作导致的运行时错误,同时满足TypeScript的类型完整性检查。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 02:45:50