React Query useMutation报错:参数无法分配给MutationKey类型
问题现象
编写的API调用服务代码如下:
const getMutationService = () => { return { createMeme: async ( _private: string, templateId: string, file: Blob, memeText?: string, title?: string, tags?: Array<string>, ): Promise<MemeCreateMemeResponse | undefined> => { return await memeApi.memePost({ _private, templateId, file, memeText, title, tags, }); }, }; };
在Hook中调用服务的代码如下:
const mutationService = getMutationService(); const { mutate: createMeme } = useMutation(mutationService.createMeme);
抛出的TypeScript类型错误:
类型为
(_private: string, templateId: string, file: Blob, memeText?: string, title?: string, tags?: Array<string>) => Promise<MemeCreateMemeResponse | undefined>的参数,无法分配给类型为MutationKey的参数。
此前其他useMutation调用均采用相同写法模式,不清楚本次抛出MutationKey相关类型错误的原因。
问题排查思路
这个报错本质是TypeScript没有匹配到useMutation接收mutationFn作为第一个参数的函数重载,错误匹配到了接收MutationKey作为第一个参数的重载,核心排查方向如下:
- 检查传入的mutation函数签名是否符合要求:TanStack Query的
useMutation规定,传入的mutationFn只能接收1个入参(即调用mutate时传入的变量),如果传入的函数是多位置参数的形式,会直接不满足mutationFn的类型约束,TS就会自动尝试匹配其他重载,最终抛出参数不匹配MutationKey的错误。 - 对比此前正常运行的同模式调用:之前没报错是因为传入的mutation函数均为单参数(通常是接收一个配置对象),刚好符合
mutationFn的类型要求,能被TS正确识别匹配重载。 - 低概率排查项:检查当前文件的
useMutation导入来源,确认是从项目使用的react-query对应包导入,没有和其他同名hook混淆。
解决方案
- 推荐方案:修改service层方法签名,将多位置参数合并为单个对象参数,完全适配mutationFn的类型要求,同时避免后续调用时出现参数顺序传错的问题。
修改后的service代码:
后续调用const getMutationService = () => { return { createMeme: async ({ _private, templateId, file, memeText, title, tags, }: { _private: string; templateId: string; file: Blob; memeText?: string; title?: string; tags?: Array<string>; }): Promise<MemeCreateMemeResponse | undefined> => { return await memeApi.memePost({ _private, templateId, file, memeText, title, tags, }); }, }; };createMeme时直接传入对象即可,TS会自动推导参数类型,不会再出现类型错误。 - 兼容方案:如果不想修改service层原有方法签名,可以在调用
useMutation时包裹一层单参数箭头函数,做参数转换适配:const { mutate: createMeme } = useMutation( (params: { _private: string; templateId: string; file: Blob; memeText?: string; title?: string; tags?: Array<string>; }) => mutationService.createMeme( params._private, params.templateId, params.file, params.memeText, params.title, params.tags ) ); - 缓存问题修复:如果确认函数签名、导入都没有问题,在编辑器中执行TypeScript服务重启(VS Code可通过命令面板执行
TypeScript: Restart TS Server),清除TS类型缓存即可。
内容的提问来源于stack exchange,提问作者dev
相关产品推荐
相关产品推荐

