使用TypeScript时Redux Toolkit的register dispatch为何不允许传参?
TypeScript报错:dispatch(register(userData))提示“0 arguments expected but received 1”
开发过不含TypeScript的MERN栈项目,目前用TypeScript开发电商网站注册页面,后端CRUD已通过Postman验证正常,但用Redux Toolkit传递用户输入数据到后端时,TypeScript报错:
0 arguments expected but received 1.ts(2554)
相关代码
注册页面组件
const Register = () => { const dispatch = useAppDispatch(); const selector = useAppSelector((state:RootState)=>state.auth); const navigate = useNavigate(); const [formdata, setFormdata] = useState({ vorname:"", nachname:"", email:"", street:"", number:"", plz:"", city:"", username:"", password:"", password_confirm:"", }) const {vorname, nachname, email, street, number, plz, city, username, password, password_confirm} = formdata; const {user, isLoading, isError, isSuccess, message} = selector; useEffect(()=>{ if(isError){ toast.error(message); } if(isSuccess || user){ navigate('/login'); } dispatch(reset); }, [dispatch, isError, isSuccess, navigate, user, message]) const handleChange = (e:ChangeEvent<HTMLInputElement>)=>{ setFormdata((prevState)=>({ ...prevState, [e.target.name]: e.target.value, })) } const onSubmit = (e:React.FormEvent)=>{ e.preventDefault(); if(password !== password_confirm){ toast.error("Die Passwörter stimmen nicht überein"); } else{ const userData = { vorname, nachname, email, street, number, plz, city, username, password, } dispatch(register(userData))// 此处报错:不应该接收参数 } };
Slice中的register异步Thunk
export const register = createAsyncThunk('/auth/register', async (user, thunkAPI)=>{ try{ return await authService.register(user!); }catch (error:any) { const message = (error.response && error.response.data && error.response.data.message) || error.message || error.toString() return thunkAPI.rejectWithValue(message as string) } })
authService中的register请求函数
const register = async (userData:object) => { const response = await axios.post(API_URL + 'register',userData); if(response.data){ localStorage.setItem('user',JSON.stringify(response.data)) } return response.data }
问题原因及解决方案
核心原因
TypeScript无法推断出createAsyncThunk创建的register thunk接受参数——因为你没有为thunk的输入参数指定类型,导致TS默认认为这个thunk不需要参数,传参时就会触发报错。
解决步骤
定义用户数据的具体类型
先明确注册时传递的用户数据结构,避免使用模糊的object类型:// 可放在单独的types文件,或slice文件顶部 interface RegisterUserData { vorname: string; nachname: string; email: string; street: string; number: string; plz: string; city: string; username: string; password: string; } // 若有后端返回的用户类型,也可同步定义 interface User { id: string; vorname: string; // 其他用户字段... }为createAsyncThunk指定泛型参数
在创建thunk时,明确指定返回值类型和输入参数类型:export const register = createAsyncThunk< User, // 第一个泛型:thunk成功时的返回值类型(对应authService.register的返回值) RegisterUserData // 第二个泛型:传递给thunk的参数类型 >('/auth/register', async (user, thunkAPI) => { try { return await authService.register(user); } catch (error: any) { const message = (error.response && error.response.data && error.response.data.message) || error.message || error.toString(); return thunkAPI.rejectWithValue(message as string); } });更新authService的参数类型
将userData: object替换为刚定义的RegisterUserData,让类型更严谨:const register = async (userData: RegisterUserData) => { const response = await axios.post(API_URL + 'register', userData); if (response.data) { localStorage.setItem('user', JSON.stringify(response.data)); } return response.data; };确保useAppDispatch的类型正确
检查store的类型定义,确保useAppDispatch能正确推断dispatch的类型:// store.ts import { configureStore } from '@reduxjs/toolkit'; import authReducer from './slices/authSlice'; export const store = configureStore({ reducer: { auth: authReducer, }, }); export type RootState = ReturnType<typeof store.getState>; export type AppDispatch = typeof store.dispatch;然后在自定义hooks中导出类型化的dispatch和selector:
// hooks.ts import { useDispatch, useSelector } from 'react-redux'; import type { TypedUseSelectorHook } from 'react-redux'; import type { RootState, AppDispatch } from './store'; export const useAppDispatch: () => AppDispatch = useDispatch; export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
完成以上步骤后,TypeScript就能正确识别register thunk接受RegisterUserData类型的参数,dispatch(register(userData))的报错会自动消失。
内容的提问来源于stack exchange,提问作者Roman
相关产品推荐
相关产品推荐

