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

如何为React Hooks的useReducer传递泛型类型

如何给React useReducer的泛型Reducer传递类型

我来帮你搞定这个泛型传递的问题!首先先修正一个语法小错误:你定义的ActionTypes接口写法不对,TypeScript里要定义动作类型枚举,得用enum而不是interface,不然switch case会报错。先把这个改过来:

// 修正ActionTypes定义
enum ActionTypes {
  FETCH = 'FETCH'
}

interface TestPayload<T> { list: T[]; }
interface State<T> { list: T[]; }
interface Action<T> { type: ActionTypes; payload: TestPayload<T>; }

export const returnAnyListReducer = <T>(
  state: State<T>,
  action: Action<T>
): State<T> => {
  const { type, payload } = action;
  switch (type) {
    case ActionTypes.FETCH: {
      return ({ ...state, list: payload.list });
    }
    // 别忘了加default case避免TypeScript报错
    default:
      return state;
  }
}

接下来,有两种直观的方式给useReducer传递你的User或AdminUser这类泛型类型:

方式一:显式给useReducer指定泛型参数

React的useReducer支持传入泛型参数,你可以直接指定State<T>和Action<T>的具体类型,同时需要导入React内置的Reducer类型来做约束:

首先定义你的业务类型,比如User:

interface User {
  id: number;
  name: string;
}

然后在组件里这样用:

import { useReducer, Reducer } from 'react';

// 显式指定initialState的类型,避免空数组被推断成never[]
const initialState: State<User> = { list: [] };

// 给useReducer传入Reducer<State<User>, Action<User>>泛型
const [state, dispatch] = useReducer<Reducer<State<User>, Action<User>>>(
  returnAnyListReducer,
  initialState
);

这样之后,dispatch的时候TypeScript会自动校验payload的类型——你必须传入TestPayload<User>类型的payload,确保list是User[],避免类型不匹配的错误。

方式二:通过initialState让TypeScript自动推断泛型

如果你给initialState指定了明确的泛型类型,TypeScript会自动匹配reducer的泛型参数,不用再给useReducer额外加泛型:

比如用AdminUser类型:

interface AdminUser {
  id: number;
  name: string;
  role: 'admin';
}

// 直接指定initialState为State<AdminUser>
const initialState: State<AdminUser> = { list: [] };

// 这里TypeScript会自动推断reducer的T为AdminUser
const [state, dispatch] = useReducer(returnAnyListReducer, initialState);

这种方式更简洁,只要initialState的类型明确,TypeScript就能自动完成泛型推导,省去手动指定泛型的步骤。

为什么之前的代码没生效?

你原来的initialState是{ list: [] },TypeScript会把空数组推断成never[],导致泛型T被推断成never,所以没法正确识别你要传入的User或AdminUser类型。只要显式给initialState指定State<T>类型,或者给useReducer指定泛型,就能解决这个问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 21:17:57