如何在Redux Toolkit中正确为action.payload设置类型?
Redux Toolkit + TypeScript 用户更新功能报错解决
报错信息
第一个错误:
The AsyncThunkFulfilledActionCreator<object, object, AsyncThunkConfig> argument cannot be assigned to the string parameter.ts(2769)
修改后出现的第二个错误:
The object argument cannot be assigned to the WritableDraft parameter. Type {} is missing the following properties of type WritableDraft: firstname, lastname, username, email, and 8 others.ts(2345)
问题根源
- AsyncThunk类型泛型太模糊:用
object作为createAsyncThunk的泛型参数,TypeScript无法正确推断action的类型,导致和addCase的参数不兼容。 - PayloadAction类型与实际返回值不匹配:更新用户接口通常返回单个用户对象,但代码里用了
User[]数组类型,同时更新逻辑用push也不符合常规更新场景(应该替换现有用户而非新增)。 - 更新参数类型太宽泛:
updateData用object类型,无法匹配User的属性要求,导致类型校验失败。
修复后的完整代码
interface User { firstname: string lastname: string username: string email: string street: string number: string plz: string city: string password: string isAdmin: boolean createdAt: Date accessToken: string; } interface InitialState { user: User[], isLoading: boolean, isSuccess: boolean, isError: boolean, message: string, } const initialState: InitialState = { user: [], isLoading: false, isSuccess: false, isError: false, message: "", } type AsyncThunkConfig = { state: RootState } // 明确泛型:返回单个User对象,参数是User的部分字段(Partial<User>) export const updateUser = createAsyncThunk<User, Partial<User>, AsyncThunkConfig>( '/user/update', async (updateData, thunkAPI) => { try { const token = thunkAPI.getState().auth.user!.accessToken; return await userService.updateUser(updateData, token); } catch (error: any) { const message = (error.response && error.response.data && error.response.data.message) || error.message || error.toString() return thunkAPI.rejectWithValue(message as string) } } ); export const userSlice = createSlice({ name: 'user', initialState, reducers: { reset: (state) => { state.isLoading = false; state.isSuccess = false; state.isError = false; state.message = ""; } }, extraReducers(builder) { builder .addCase(updateUser.pending, (state) => { state.isLoading = true; }) // 自动推断action类型,无需手动指定PayloadAction .addCase(updateUser.fulfilled, (state, action) => { state.isLoading = false; state.isSuccess = true; // 找到数组中对应的用户并替换(按email或username匹配,根据业务调整) const targetIndex = state.user.findIndex(u => u.email === action.payload.email); if (targetIndex !== -1) { state.user[targetIndex] = action.payload; } // 如果是新增用户场景,才用push:state.user.push(action.payload); }) // 补充错误状态处理 .addCase(updateUser.rejected, (state, action) => { state.isLoading = false; state.isError = true; state.message = action.payload as string; }) }, })
关键修改说明
- 精准泛型定义:把
createAsyncThunk的泛型从object, object改成User, Partial<User>,明确返回值是单个用户对象,更新参数只需要传用户的部分字段。 - 自动类型推断:移除手动指定的
PayloadAction<User[]>,Redux Toolkit会根据AsyncThunk的泛型自动生成正确的action类型,避免类型不匹配。 - 修正更新逻辑:更新用户时找到数组中对应的项进行替换,而不是直接push(如果是新增用户场景则保留push,根据实际业务调整)。
- 完善错误处理:添加
updateUser.rejected的状态处理,确保错误状态能正确更新。
内容的提问来源于stack exchange,提问作者Roman
相关产品推荐
相关产品推荐

