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

如何为Action Creator与Reducer的元组数组做TypeScript类型校验?

类型校验Action Creator与Reducer元组数组的实现方案

需求明确

  • 校验Action Creator生成的Action的Payload,与对应Reducer接收的Payload完全一致
  • 确保所有Reducer接收的State类型统一
  • 实现方案需与状态管理库无关,且无需手动维护有效Payload列表

现有方案问题

  • 函数创建元组:该方式能实现校验,但依赖函数调用生成元组,希望直接用纯数据结构(如数组字面量)完成定义
  • 简单类型助手:无法正确识别Action与Reducer的错误配对,类型校验失效

解决方案实现

1. 基础类型定义

先明确State、Action、Action Creator、Reducer的基础类型:

// 全局统一的State类型
type AppState = { count: number; name: string };

// Action基础结构
type Action<Type extends string, Payload = void> = {
  type: Type;
  payload?: Payload;
};

// Action Creator类型:返回对应类型的Action
type ActionFn<Type extends string, Payload = void> = Payload extends void
  ? () => Action<Type>
  : (payload: Payload) => Action<Type, Payload>;

// Reducer类型:接收统一State和对应Action,返回新State
type Reducer<Payload = void> = (
  state: AppState,
  action: Action<string, Payload>
) => AppState;

2. 核心类型校验助手

定义类型工具,强制单个元组中的Action Creator与Reducer的Payload匹配:

// 提取Action Creator的Payload类型
type ExtractActionPayload<Fn> = Fn extends ActionFn<string, infer P> ? P : never;

// 校验单个[ActionCreator, Reducer]元组的合法性
type ValidActionReducerPair<T> = T extends [ActionFn<string, infer P>, Reducer<P>]
  ? T
  : never;

// 校验整个数组的所有元组都符合规则
type ValidActionReducerArray = Array<ValidActionReducerPair<[ActionFn, Reducer]>>;

3. 实际使用示例

正确配对示例

// 定义符合规则的Action Creator和Reducer
const actionA: ActionFn<'INCREMENT', number> = (payload) => ({ type: 'INCREMENT', payload });
const reducerA: Reducer<number> = (state, action) => ({ ...state, count: state.count + action.payload! });

const actionB: ActionFn<'SET_NAME', string> = (payload) => ({ type: 'SET_NAME', payload });
const reducerB: Reducer<string> = (state, action) => ({ ...state, name: action.payload! });

// 合法的元组数组:类型校验通过
const validPairs: ValidActionReducerArray = [
  [actionA, reducerA],
  [actionB, reducerB]
];

错误配对示例

// 错误配对:Action的Payload是number,Reducer期望string
const invalidPairs: ValidActionReducerArray = [
  [actionA, reducerB] // 类型报错:元组类型不匹配
];

方案说明

  • 利用TypeScript的条件类型和类型推断,自动提取Action Creator的Payload类型,与Reducer的Payload类型做强制匹配
  • 无需手动维护Payload列表,所有类型推导完全基于Action Creator和Reducer的定义
  • 纯数据结构(数组字面量)定义元组数组,同时保留严格的类型校验

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 18:44:51