tRPC+Prisma组件增删Record时类型错误求助
解决tRPC Mutation调用的类型错误问题
问题描述
在React组件中实现创建和删除Prisma记录功能时,路由配置无错误,但组件调用mutation时出现类型不匹配错误,报错集中在创建和删除任务的参数传递环节。
错误信息
Argument of type '{ input: { title: string; content: string; assigneeId: string; }; }' is not assignable to parameter of type 'void'.ts(2345)
Argument of type '{ id: string; }' is not assignable to parameter of type 'void'.ts(2345)
相关代码
Tasks.ts(路由定义)
import { z } from "zod"; export const TaskCreateInput = z.object({ title: z.string(), content: z.string(), assigneeId: z.string(), }); export const TaskDeleteInput = z.object({ id: z.string(), }); import { createTRPCRouter, publicProcedure, } from "~/server/api/trpc"; export const tasksRouter = createTRPCRouter({ getAll: publicProcedure.query(({ ctx }) => { return ctx.prisma.task.findMany(); }), createTask: publicProcedure.mutation(({ ctx, input }) => { const validatedInput = TaskCreateInput.parse(input); return ctx.prisma.task.create({ data: validatedInput, }); }), deleteTask: publicProcedure.mutation(({ ctx, input }) => { const validatedInput = TaskDeleteInput.parse(input); return ctx.prisma.task.delete({ where: { id: validatedInput.id, }, }); }), });
Maintenance.tsx(React组件)
import React, {useState } from "react"; import { api } from "~/utils/api"; import type { TaskCreateInput, TaskDeleteInput } from "~/server/api/routers/tasks"; const Maintenance = () => { const { data } = api.tasks.getAll.useQuery(); const createTaskMutation = api.tasks.createTask.useMutation(); const deleteTaskMutation = api.tasks.deleteTask.useMutation(); const [title, setTitle] = useState(""); const [content, setContent] = useState(""); const [assigneeId, setAssigneeId] = useState(""); const handleCreateTask = () => { createTaskMutation.mutate({ input: { title, content, assigneeId } }, { onSuccess: () => { setTitle(""); setContent(""); setAssigneeId(""); }, }); }; const handleDeleteTask = (id: string) => { deleteTaskMutation.mutate({ id: id }, { onSuccess: () => { // handle success }, }); }; return ( <> <div className="mb-4"> <input className="mr-2" type="text" placeholder="Title" value={title} onChange={(e) => setTitle(e.target.value)}/> <input className="mr-2" type="text" placeholder="Content" value={content} onChange={(e) => setContent(e.target.value)}/> <input className="mr-2" type="text" placeholder="Asignee" value={assigneeId} onChange={(e) => setAssigneeId(e.target.value)}/> <button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded" onClick={handleCreateTask}> Add Task </button> </div> {data?.map((task) => ( <div key={task.id} className="max-w-sm rounded overflow-hidden shadow-lg mb-4 flex flex-row bg-red-500"> <div className="px-6 py-4"> <div className="font-bold text-xl mb-2">{task.title}</div> <p className="font-light text=gray-700 text-base">{task.content}</p> <h2>Assigned to: {task.assigneeId}</h2> </div> <button className="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded" onClick={() => handleDeleteTask(task.id)}> Delete </button> </div> ))} </> ); }; export default Maintenance;
解决方案
1. 修正tRPC路由的输入schema配置
问题根源是tRPC的publicProcedure未明确指定输入schema,导致客户端生成的mutation类型默认参数为void,无法匹配传入的对象。需要在路由定义中为每个mutation添加.input()方法绑定对应的Zod schema:
修改后的Tasks.ts中mutation部分:
createTask: publicProcedure .input(TaskCreateInput) .mutation(({ ctx, input }) => { // tRPC会自动验证输入,无需手动调用parse return ctx.prisma.task.create({ data: input, }); }), deleteTask: publicProcedure .input(TaskDeleteInput) .mutation(({ ctx, input }) => { return ctx.prisma.task.delete({ where: { id: input.id, }, }); }),
2. 调整客户端mutation调用的参数格式
移除不必要的input包裹字段,直接传入符合schema定义的对象:
修改后的Maintenance.tsx中处理函数部分:
const handleCreateTask = () => { createTaskMutation.mutate({ title, content, assigneeId }, { onSuccess: () => { setTitle(""); setContent(""); setAssigneeId(""); }, }); }; const handleDeleteTask = (id: string) => { deleteTaskMutation.mutate({ id }, { onSuccess: () => { // handle success }, }); };
说明
- tRPC通过
.input()绑定schema后,会自动完成输入验证和类型推断,客户端调用时就能获得正确的参数类型提示,避免类型错误。 - 移除手动的
parse调用,简化代码逻辑,同时利用tRPC内置的验证机制保证输入合法性。
内容的提问来源于stack exchange,提问作者FunctionUndefined
相关产品推荐
相关产品推荐

