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

使用TypeScript/RTK时如何定义rejected场景下payload对象的类型

问题解决方案

你遇到的报错根源有两个:

  1. 没有给createAsyncThunk声明rejectValue的类型,TS默认将rejected状态的payload推导为unknown
  2. 你在rejectWithValue里传的是字符串类型的error.message,但reducer里却尝试取payload.message,属于逻辑错误,字符串本身没有message属性

步骤1:给两个createAsyncThunk添加完整泛型声明

createAsyncThunk支持传入三个泛型参数,分别为:

  • 第1位:异步请求成功后的返回值类型
  • 第2位:thunk的入参类型
  • 第3位:配置项,用来声明rejectValue的类型

修改后的thunk代码如下:

// 修改forgotPasswordRequest的泛型声明
export const forgotPasswordRequest = createAsyncThunk<
  null, // 成功后返回null
  ForgotPasswordRequestProps, // 入参类型
  { rejectValue: string } // rejectWithValue返回的值为string类型
>(
  'auth/forgotPasswordRequest',
  async (data, { rejectWithValue }) => {
    const { email } = data;
    try {
      const response = await Axios.anon.post(`/v1/auth/forgot-password`, { email });
      if (response.status === 204) return null;
    } catch (error) {
      if (error instanceof Error) return rejectWithValue(error.message);
      // 统一兜底返回错误信息,避免返回undefined
      return rejectWithValue('未知错误');
    }
  }
);

// 同理修改forgotPasswordSet的泛型声明
export const forgotPasswordSet = createAsyncThunk<
  null,
  ForgotPasswordSetProps,
  { rejectValue: string }
>(
  'auth/verifyEmailSet',
  async (data, { rejectWithValue }) => {
    const { query, password } = data;
    try {
      const response = await Axios.anon.post(`/v1/auth/reset-password?token=${query}`, { password });
      if (response.status === 204) return null;
    } catch (error) {
      if (error instanceof Error) return rejectWithValue(error.message);
      return rejectWithValue('未知错误');
    }
  }
);

步骤2:修改rejected分支的逻辑

添加泛型后TS可以自动推导payload为string | undefined类型,不需要额外手动标注action类型,同时修正取值逻辑:

.addCase(
  forgotPasswordRequest.rejected, (state, action) => {
    state.status.isPending = false;
    state.status.isError = true;
    // 直接用payload,加兜底避免undefined
    state.status.errorMessage = action.payload ?? '请求失败';
  }
)
.addCase(
  forgotPasswordSet.rejected, (state, action) => {
    state.status.isPending = false;
    state.status.isError = true;
    state.status.errorMessage = action.payload ?? '请求失败';
  }
)

可选手动标注方案

如果你需要明确手动标注action类型,可以导入PayloadAction后指定类型:

import type { PayloadAction } from '@reduxjs/toolkit';

.addCase(
  forgotPasswordRequest.rejected, 
  (state, action: PayloadAction<string | undefined>) => {
    state.status.errorMessage = action.payload ?? '请求失败';
  }
)

修改完成后所有类型错误都会消失,逻辑也符合你实际的返回值规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 22:09:01