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

如何在reduxjs/toolkit的extraReducer中设置action类型解决类型报错

报错核心原因
  • 未给createAsyncThunk传入正确的泛型参数,导致返回的action.payload类型被推导为unknown
  • catch块直接return error的逻辑错误:createAsyncThunk只有抛出错误/调用rejectWithValue才会触发rejected状态,直接返回错误会被判定为请求成功,同时导致TS推导返回值类型为MovieModel[] | Error,和标注的返回类型冲突
  • 之前传入泛型时缺少第二个入参类型的声明,导致类型不匹配
修正方案

方案一:使用rejectWithValue返回自定义错误(推荐)

  1. 修正thunk的类型定义与错误处理逻辑:
import { createAsyncThunk } from '@reduxjs/toolkit';
// 注意替换为你自己的类型定义文件路径
import { MovieModel, MyApiResponse } from './types';

// 泛型参数依次为:成功返回值类型、thunk入参类型、reject返回值类型
export const fetchMoviesAsync = createAsyncThunk<
  MovieModel[],
  void,
  { rejectValue: string }
>('movies/fetchMoviesAsync', async (_, { rejectWithValue }) => {
  try {
    const response = await fetch(
      'https://react-movies-b6b21-default-rtdb.firebaseio.com/movies.json'
    );
    if (!response.ok) {
      throw new Error('Error fetching data 🐱‍👤');
    }
    const data = await response.json();

    const transformedData: MovieModel[] = Object.entries(data as MyApiResponse).map(([key, value]) => {
      return {
        ...value,
        id: key,
      };
    });
    return transformedData;
  } catch (error) {
    // 用rejectWithValue返回错误,触发rejected状态
    return rejectWithValue((error as Error).message);
  }
});
  1. 此时slice中的类型会被RTK自动推导,无需额外修改,action.payload在fulfilled状态下自动为MovieModel[]类型,赋值给state.movies不会再报错。

方案二:直接抛出错误

如果不需要自定义返回错误格式,可以直接抛出错误,无需使用rejectWithValue:

  1. thunk代码:
export const fetchMoviesAsync = createAsyncThunk<MovieModel[], void>(
  'movies/fetchMoviesAsync', 
  async () => {
    const response = await fetch(
      'https://react-movies-b6b21-default-rtdb.firebaseio.com/movies.json'
    );
    if (!response.ok) {
      throw new Error('Error fetching data 🐱‍👤');
    }
    const data = await response.json();
    const transformedData: MovieModel[] = Object.entries(data as MyApiResponse).map(([key, value]) => {
      return {
        ...value,
        id: key,
      };
    });
    return transformedData;
});
  1. 修正slice中rejected逻辑的取值路径:
builder.addCase(fetchMoviesAsync.rejected, (state, action) => {
  state.isFetching = false;
  // 直接抛出的错误会存放在action.error对象中
  state.errorMessage = action.error.message;
});
优化建议

当前slice的name字段取值为movies/fetchMoviesAsync,属于不合理命名,slice的name为全局命名空间,建议修改为name: 'movies',避免后续生成的action type出现前缀重复问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 08:06:04