在Next.js中使用react-query的useMutation时遇TypeScript错误
解决Next.js + React Query + TypeScript订阅表单的API请求类型错误
遇到的错误
- 调用
mutate(email)时提示:
Argument of type 'string' is not assignable to parameter of type 'void'
- 定义
useEmailSubscription时提示:
Type (email: string)=> Promise <AxiosResponse <any, any>> has no properties in common with type 'UseMutationOptions<unknown, Error, void, unknown'
错误原因
两个错误本质都是React Query的useMutation未正确推断或指定类型参数:
- TypeScript默认将mutation的变量类型推断为
void,导致mutate函数不接受参数,与传入的string类型冲突。 - mutation回调函数接受
string参数,但UseMutationOptions的变量类型被推断为void,引发类型不匹配。
解决方案
显式为useMutation指定类型参数,确保TypeScript正确识别变量类型:
修正请求代码
首先定义API返回数据的类型(根据实际接口调整,无明确结构可使用unknown):
// 自定义API返回类型示例 interface EmailSubscriptionResult { success: boolean; message: string; } export const useEmailSubscription = () => { // 显式指定类型参数:返回类型、错误类型、变量类型 return useMutation<EmailSubscriptionResult, Error, string>( (email: string) => axiosOpen.post('/email-subscriptions', { email }) ); };
如果不需要自定义返回类型,也可以让TS自动推断(但显式指定类型在复杂场景下更可靠):
export const useEmailSubscription = () => { return useMutation((email: string) => axiosOpen.post('/email-subscriptions', { email }) ); };
表单组件代码无需修改
修正请求代码后,TypeScript会自动识别mutate接受string类型参数,原表单组件的mutate(email)调用不再报错。
额外优化建议
- 为
axiosOpen配置请求/响应类型,避免any类型,增强整体类型安全性。 - 添加回调处理订阅结果:
export const useEmailSubscription = () => { return useMutation<EmailSubscriptionResult, Error, string>( (email: string) => axiosOpen.post('/email-subscriptions', { email }), { onSuccess: (res) => { console.log('订阅成功:', res.message); // 可在此重置表单输入或展示成功提示 }, onError: (err) => { console.error('订阅失败:', err.message); // 可在此展示错误提示 } } ); };
内容的提问来源于stack exchange,提问作者Rahil Əliyev
相关产品推荐
相关产品推荐

