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

Typescript中如何给Redux-Toolkit createAsyncThunk的rejected payload指定string类型

环境
  • Redux-Toolkit
  • React
  • Typescript
  • GraphQL
背景

我使用redux和redux-toolkit做本地状态管理,查阅redux-toolkit官方文档可知,可以通过其提供的createAsyncThunk()方法派发thunk异步action,该方法会自动派发pending、fulfilled、rejected三种类型的action。
异步任务执行失败时,thunk会派发rejected类型的action,默认情况下action.error为SerializedError类型,我们可以通过rejectWithValue()方法自定义错误返回结果,示例代码如下:

const fetchAdminPassword = createAsyncThunk('adminPassword/fetch', async (_, { rejectWithValue }) => {
  try {
    const result = await client.query<{adminPassword: string}>({ query: FETCH_ADMIN_PASSWORD });
    const { data: { adminPassword } } = result;
    return adminPassword;
  } catch (err) {
    rejectWithValue("Error!!");
  }
});


builder.addCase(fetchAdminPassword.rejected, (state, action) => {
  state.fetchError = action.payload;
  state.fetchPending = false;
})
问题

上述示例代码中,rejected回调内的action.payload类型为unknown,如何将其类型修改为string?


解决方案

要为rejected状态的action.payload指定string类型,最标准的做法是给createAsyncThunk传入泛型参数,明确定义rejectWithValue的返回值类型:

  1. createAsyncThunk支持传入三个泛型参数,依次为:
    • 异步函数成功返回值的类型
    • thunk接收的入参类型(你当前的代码没有入参,所以填void)
    • 配置项类型,这里只需要指定rejectValue为string即可
  2. 注意你当前的示例代码有个疏漏:catch分支里必须return rejectWithValue("Error!!"),否则返回值为undefined,类型匹配也会异常。

修改后的完整代码如下:

// 给createAsyncThunk传入泛型定义
const fetchAdminPassword = createAsyncThunk<string, void, { rejectValue: string }>(
  'adminPassword/fetch',
  async (_, { rejectWithValue }) => {
    try {
      const result = await client.query<{adminPassword: string}>({ query: FETCH_ADMIN_PASSWORD });
      const { data: { adminPassword } } = result;
      return adminPassword;
    } catch (err) {
      // 这里必须加return
      return rejectWithValue("Error!!");
    }
  }
);

builder.addCase(fetchAdminPassword.rejected, (state, action) => {
  // 此时action.payload的类型会自动推导为string | undefined
  state.fetchError = action.payload;
  state.fetchPending = false;
})

如果你不想修改createAsyncThunk的定义,也可以在addCase回调中临时使用类型断言:

builder.addCase(fetchAdminPassword.rejected, (state, action) => {
  state.fetchError = action.payload as string;
  state.fetchPending = false;
})

不过这种方法没有编译期类型校验,更推荐使用泛型定义的方案。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 02:15:08