You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用React Query useMutation时遭遇TypeScript类型错误求助

问题解决:React Query useMutation 类型错误

错误原因

TypeScript 无法自动推断 useMutation 中 mutationFn 的参数类型,导致 mutate 函数的参数被错误推断为 void,与你传入的表单数据类型不匹配。

解决方案

步骤1:定义明确的类型

从 Zod Schema 中导出表单输入类型,再定义适配 API 的请求类型(因为你把 answers 从字符串转成了数组):

import { z } from 'zod';

// 示例:你的 createPoolSchema 定义(根据实际情况调整)
const createPoolSchema = z.object({
  question: z.string(),
  answers: z.string(), // 表单中为逗号分隔的字符串
  expiresAt: z.date(),
  isPublic: z.boolean(),
});

// 导出表单输入的类型
type CreatePoolFormInput = z.infer<typeof createPoolSchema>;
// 定义 API 请求需要的类型(answers 转为数组)
type CreatePoolApiRequest = Omit<CreatePoolFormInput, 'answers'> & { answers: string[] };

步骤2:给 useMutation 补充类型注解

通过给 mutationFn 的参数添加类型,让 TypeScript 正确识别 mutate 接收的参数类型:

const { mutate } = useMutation({
  mutationFn: (data: CreatePoolApiRequest) => {
    return axios.post('/api/pool', data);
  },
  onSuccess: () => {
    toast.success('Pool created');
  },
});

也可以通过指定泛型参数的方式实现:

const { mutate } = useMutation<axios.AxiosResponse, unknown, CreatePoolApiRequest>({
  mutationFn: (data) => {
    return axios.post('/api/pool', data);
  },
  onSuccess: () => {
    toast.success('Pool created');
  },
});

步骤3:确认 useForm 封装的正确性

你的自定义 useForm 已经正确基于 Zod Schema 推断类型,这部分无需修改,只需确保 createPoolSchema 的定义符合业务需求即可。

完整修正后的代码

import { z } from 'zod';
import { useForm } from './path-to-your-useForm'; // 替换为你的 useForm 文件路径
import { useMutation } from '@tanstack/react-query';
import axios from 'axios';
import { toast } from 'react-hot-toast';

// 定义 Zod 校验规则
const createPoolSchema = z.object({
  question: z.string(),
  answers: z.string(),
  expiresAt: z.date(),
  isPublic: z.boolean(),
});

type CreatePoolFormInput = z.infer<typeof createPoolSchema>;
type CreatePoolApiRequest = Omit<CreatePoolFormInput, 'answers'> & { answers: string[] };

export const useCreatePoolForm = () => {
  const { submit, register, errors, watch } = useForm(createPoolSchema);

  const { mutate } = useMutation({
    mutationFn: (data: CreatePoolApiRequest) => {
      return axios.post('/api/pool', data);
    },
    onSuccess: () => {
      toast.success('Pool created');
    },
  });

  const createPool = submit((pool) => {
    const answersToArray = pool.answers.split(',').map(answer => answer.trim());

    mutate({
      ...pool,
      answers: answersToArray,
    });
  });

  return {
    createPool,
    register,
    errors,
    watch,
  };
};

内容的提问来源于stack exchange,提问作者IvonaK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 05:07:35