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

如何将Zod Schema指定属性设为可选以适配Upsert场景?

解决方案

方法1:直接指定单个属性为可选

如果不需要保留原有的严格校验schema(用于数据库返回结果),可以直接在定义时给id字段加上.optional():

const upsertSchema = z.object({
    id: z.string().optional(),
    name: z.string(),
});

这样既满足id可选的需求,又保证name字段必填。

方法2:基于原Schema扩展(推荐)

因为原schema要用于数据库返回结果(id为必填主键),推荐通过extend方法复用原schema,仅修改id的约束:

// 原数据库返回用的schema,保持不变
const dbReturnSchema = z.object({
    id: z.string(),
    name: z.string(),
});

// 创建Upsert专用schema,将id设为可选
const upsertSchema = dbReturnSchema.extend({
    id: z.string().optional(),
});

这种方式避免重复定义字段,同时保留原schema的完整性。

方法3:用omit/partial组合实现

也可以通过omit移除原schema的id,再合并一个可选的id字段:

const upsertSchema = dbReturnSchema.omit({ id: true }).merge(z.object({ id: z.string().optional() }));

或者使用partial仅将指定字段设为可选,再和原schema合并:

const upsertSchema = z.partial({ id: true }).merge(dbReturnSchema);

z.partial({ id: true })只会对id字段应用可选约束,其他字段保持原有的必填要求。

测试验证

使用新的upsertSchema处理Upsert逻辑:

// 插入操作正常通过解析
const insertData = upsertSchema.parse({ name: 'My Name' });

// 更新操作正常通过解析
const updateData = upsertSchema.parse({ id: '123', name: 'My Name' });

user.upsert({ ...insertData, id: insertData?.id || generateId() });

此时Zod不会再抛出id字段缺失的错误,同时确保name字段始终存在。


内容的提问来源于stack exchange,提问作者Bambang Adhitya Permana

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 06:27:47