首页 新闻 会员 周边 捐助

tRPC是否支持部分参数的验证以确保更新只传入必要的参数?

0
[待解决问题] 浏览: 11次

tRPC 一般是使用z.object()来进行参数验证的。

举例:

interface Proj {
  id: number,
  projName: string,
  desc?: string
}


export const projUpdate = publicProcedure.input(
  z.object({
    id: z.number(),
    projName: z.string(),
    desc: z.string()
  })
).mutation(({ input: {id, projName, desc} }) => {
  dataBase.getRepository(Proj).createQueryBuilder('proj').where('proj.id = :id', {id: id}).update({
    projName: projName,
    desc: desc
  })
})

现在有一个需求问题:
1、请问是否是可以进行类型Proj验证呢?因为更新实例Proj,我们一般传输部分参数为:Partial<Proj>即可,但是这里是:
全验证:

z.object({
    id: z.number(),
    projName: z.string(),
    desc: z.string()
  })

2、表现:使用时候报错:

export const addProj = async(proj: Proj) => {
  return await trpc.projCreate.mutate(proj)  // 这里报错
}

请问是否可以进行Partial 可选参数传入更新呢?

架构师之路123的主页 架构师之路123 | 初学一级 | 园豆:164
提问于:2024-12-19 18:08
< > 人人可用的开源BI工具
分享
所有回答(1)
0

是的,tRPC 可以支持部分参数的验证,以确保在更新操作中只传入必要的参数。你可以使用 z.object 结合 z.optional 或者使用 TypeScriptPartial<T> 类型定义来实现这一点。

实现步骤

  1. 使用 Zod 定义可选属性
    使用 z.optional 来定义哪些属性是可选的。这使得你可以根据需要传入部分参数。

  2. 更新输入类型
    使用 z.object 来验证只包含需要更新的属性,符合 Partial<Proj> 的定义。

具体代码示例

下面是更新后的示例代码,展示了如何使用可选参数来实现你的需求:

import { z } from 'zod';
import { createTRPCRouter, publicProcedure } from '@trpc/server';

interface Proj {
  id: number;
  projName: string;
  desc?: string;
}

// 定义类型,只允许指定的属性进行更新
const projUpdateInput = z.object({
  id: z.number(),
  projName: z.string().optional(),
  desc: z.string().optional()
});

// 更新的mutation
export const projUpdate = publicProcedure.input(projUpdateInput).mutation(async ({ input }) => {
  const { id, projName, desc } = input;

  // 创建查询构建器
  const updateData: Partial<Proj> = {
    ...(projName !== undefined && { projName }),
    ...(desc !== undefined && { desc })
  };
  
  await dataBase.getRepository(Proj)
    .createQueryBuilder('proj')
    .where('proj.id = :id', { id })
    .update(updateData)
    .execute();
});

// 在调用时,允许传入部分参数
export const addProj = async (proj: Partial<Proj> & { id: number }) => {
  // 这里可以传入 projName 和 desc 的值也可以不传,
  return await trpc.projUpdate.mutate(proj);
}

代码解析

  1. 定义projUpdateInput
    使用 z.object 定义要更新的参数。projNamedesc 已被设为可选(.optional()),允许在调用时不传递这些参数。

  2. 使用 Partial<Proj>
    mutation 中,updateData 根据实际传入的值生成一个部分更新对象。如果 projNamedescundefined,则不会在对象中包含这些属性。

  3. 调用函数
    addProj 函数中,你可以传递一个部分的 Proj 对象,确保 id 是必需的,其他字段可以是可选的。这样用户可以根据需要更新字段。

优势

  • 灵活性:允许用户传入包含所需字段的完整对象,也允许他们选择只传入需要更新的字段。
  • 类型安全:使用 TypeScript 和 Zod,确保类型在编译时被验证,减少运行时错误。

这种方法结合了 TypeScript 的灵活性和强类型,同时受益于 Zod 的验证功能,确保数据的完整性。希望这可以解决你的问题!如果有任何疑问或需要进一步的帮助,随时告诉我!

Technologyforgood | 园豆:7872 (大侠五级) | 2025-01-20 09:24
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册
Top