如何为PayloadAction设置正确的LoginError类型?
正确设置Redux Toolkit登录错误的PayloadAction类型
核心问题原因
直接给login.rejected指定PayloadAction<LoginError>报错,是因为Redux Toolkit的createAsyncThunk默认的rejected action payload类型并非你定义的LoginError——默认情况下,rejected的payload可能是unknown或原生Error对象,和自定义类型不匹配。必须通过配置thunk的泛型参数+使用rejectWithValue返回结构化错误,让TypeScript识别正确的payload类型。
分步解决代码示例
1. 定义LoginError类型
type LoginError = { message: string; status: number; };
2. 配置createAsyncThunk的泛型参数
在创建登录异步thunk时,明确指定rejectValue的类型为LoginError,同时在异步逻辑中用rejectWithValue返回符合结构的错误数据,而非直接抛出原生Error:
import { createAsyncThunk, createSlice, PayloadAction } from '@reduxjs/toolkit'; // 假设登录成功返回的用户类型 type User = { id: string; username: string; }; export const login = createAsyncThunk< User, // 登录成功时的返回类型 { username: string; password: string }, // 登录参数类型 { rejectValue: LoginError } // 明确rejected时的payload类型 >('auth/login', async (credentials, { rejectWithValue }) => { try { const response = await fetch('/api/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(credentials), }); if (!response.ok) { const errorRes = await response.json(); // 用rejectWithValue返回符合LoginError结构的错误 return rejectWithValue({ message: errorRes.message || '登录失败', status: response.status, }); } return response.json(); } catch (err) { // 处理网络等异常,同样返回结构化错误 return rejectWithValue({ message: '网络连接异常', status: 0, }); } });
3. 在slice中处理rejected action
此时login.rejected的payload会自动推导为LoginError类型(可能为undefined,需做兜底处理):
const authSlice = createSlice({ name: 'auth', initialState: { user: null as User | null, error: null as LoginError | null, loading: false, }, reducers: {}, extraReducers: (builder) => { builder .addCase(login.pending, (state) => { state.loading = true; state.error = null; }) .addCase(login.rejected, (state, action: PayloadAction<LoginError | undefined>) => { state.loading = false; // 这里action.payload已正确识别为LoginError类型 state.error = action.payload || { message: '未知错误', status: 0 }; }) .addCase(login.fulfilled, (state, action) => { state.loading = false; state.user = action.payload; state.error = null; }); }, }); export const authReducer = authSlice.reducer;
关键注意点
- 必须使用
rejectWithValue返回错误:直接throw new Error()会导致action.payload为undefined,错误信息会放在action.error中,无法匹配自定义的LoginError类型。 - 泛型参数不可省略:只有在
createAsyncThunk的泛型中指定rejectValue: LoginError,TypeScript才能正确推导rejected action的payload类型。
内容的提问来源于stack exchange,提问作者code_learner93
相关产品推荐
相关产品推荐

