Redux Toolkit+TypeScript认证:如何为action.payload指定类型?
解决Redux Toolkit + TypeScript中Action Payload的类型报错问题
你这问题核心就是没给Redux的Action Payload和State定义清晰的TypeScript类型,导致赋值时类型不兼容。下面是具体的修复步骤:
1. 先把核心类型抽成别名
先把用到的用户信息、请求参数这些类型单独定义,避免重复编写,同时让类型逻辑更清晰:
// 匹配你state里userInfo的结构 type UserInfo = { userId: string; email: string; }; // 注册请求的参数类型 type SignUpParams = { name: string; email: string; password: string; avatar: string; };
2. 修正createAsyncThunk的类型约束
你的signUp异步Thunk现在返回的是string | null,如果注册成功后后端会返回用户信息,那得把返回类型改成UserInfo | null;要是后端不返回用户信息,当前返回类型没问题,但要确保后续逻辑匹配。另外,明确rejectWithValue的类型:
import { createAsyncThunk, createSlice, PayloadAction } from "@reduxjs/toolkit"; import axios from "axios"; const signUp = createAsyncThunk< UserInfo | null, // 成功时的返回类型,按需调整 SignUpParams, { rejectValue: string } // 明确失败时返回的payload类型 >( "user/signup", async ({ name, email, password, avatar }, { rejectWithValue }) => { try { const config = { headers: { "Content-Type": "application/json", }, }; // 如果后端注册成功返回用户信息,这里要接收并返回 const response = await axios.post<UserInfo>( `${backendURL}/api/user/register`, { name, email, password, avatar }, config ); return response.data; // 后端不返回用户信息的话就保持return null } catch (error: any) { if (error.response && error.response.data.message) { return rejectWithValue(error.response.data.message); } else { return rejectWithValue(error.message); } } } );
3. 给Slice里的Reducer指定Payload类型
处理setCredentials的类型报错
在reducers里的setCredentials,必须明确它的Payload类型是UserInfo,这样TypeScript就能识别action.payload的类型:
// 先定义State的类型 type AuthState = { userToken: string | null; loading: boolean; userInfo: UserInfo | null; error: string | null; success: boolean; }; const initialState: AuthState = { userToken: localStorage.getItem("userToken") || null, // 假设token存在localStorage loading: false, userInfo: null, error: null, success: false, }; const authSlice = createSlice({ name: "authen", initialState, reducers: { logout: (state) => { localStorage.removeItem("userToken"); state.loading = false; state.userInfo = null; state.userToken = null; state.error = null; }, // 用PayloadAction明确payload类型 setCredentials: (state, action: PayloadAction<UserInfo>) => { state.userInfo = action.payload; }, }, extraReducers: (builder) => { builder .addCase(signUp.pending, (state) => { state.loading = true; state.error = null; }) .addCase(signUp.fulfilled, (state, action) => { state.loading = false; state.success = true; // 如果signUp成功返回了用户信息,直接赋值 if (action.payload) { state.userInfo = action.payload; } }) .addCase(signUp.rejected, (state, action) => { state.loading = false; // 这里payload类型已经被约束为string,直接赋值即可 state.error = action.payload || null; }); }, });
关键注意点
- 所有涉及Payload的Action,必须明确指定类型,TypeScript才能正确做类型检查。
createAsyncThunk的第三个泛型参数{ rejectValue: string }是用来约束失败时返回的payload类型,这样在rejected分支里,action.payload就会被识别为string | undefined。PayloadAction是Redux Toolkit自带的类型,用来描述带Payload的Action,记得从@reduxjs/toolkit导入。
这样改完之后,你给state.userInfo赋值时就不会再出现类型错误了,TypeScript会自动校验payload的类型是否匹配。
内容的提问来源于stack exchange,提问作者Minh Thông
相关产品推荐
相关产品推荐

