如何合并多个Zod对象Schema实现三种博客文章类型验证
合并三种博客文章Zod Schema的解决方案
要合并这三个用于博客文章的Zod Schema,最简洁高效的方式是使用Zod的**discriminatedUnion(鉴别联合类型)**方法——因为三个Schema共享attachmentType这个可用于区分类型的字段,用它来做鉴别键能让验证逻辑更清晰、性能更优。
实现代码
import { z } from 'zod'; // 图片帖Schema(补全attachment的验证逻辑,可根据实际需求替换) const imagePostSchema = z.object({ body: z.string().max(500).optional().or(z.literal('')), attachmentType: z.literal('img'), attachment: z.instanceof(File), // 示例:验证为图片文件,可替换为URL/其他规则 }); // 视频帖Schema(补全attachment的验证逻辑) const videoPostSchema = z.object({ body: z.string().max(500).optional().or(z.literal('')), attachmentType: z.literal('video'), attachment: z.instanceof(File), // 示例:验证为视频文件,可替换为URL/其他规则 }); // 文本帖Schema const textPostSchema = z.object({ body: z.string().max(500), attachmentType: z.null(), attachment: z.null(), }); // 合并为单一Schema,以attachmentType作为鉴别字段 const postSchema = z.discriminatedUnion('attachmentType', [ imagePostSchema, videoPostSchema, textPostSchema, ]); // 可选:获取合并后的类型定义 type Post = z.infer<typeof postSchema>;
关键说明
- 鉴别联合类型的优势:
相比普通的z.union,discriminatedUnion会直接根据attachmentType的具体值匹配对应的子Schema,无需逐个尝试验证,验证速度更快,同时TypeScript的类型推断也更精准。 - 验证规则保持原样:
合并后的Schema完全保留了三个子Schema的验证逻辑:- 图片/视频帖:
body可选或为空字符串,必须对应类型的附件和attachmentType; - 文本帖:
body必填,attachmentType和attachment必须为null。
- 图片/视频帖:
- 自定义附件验证:
代码中attachment的验证用了z.instanceof(File)作为示例,你可以根据实际场景替换为图片/视频的URL验证(比如z.string().url())、文件格式校验等逻辑。
内容的提问来源于stack exchange,提问作者Md. A. A. Apu
相关产品推荐
相关产品推荐

