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

如何在TypeScript中为条件类型验证创建单个Zod Schema?

用单个Zod Schema验证带类型专属字段的RichText类型

当然可以,你可以利用Zod的discriminatedUnion特性,创建一个单个的Schema,实现和TypeScript的RichText类型完全匹配的验证逻辑,无需手动判断使用哪个子Schema。

问题回顾

你定义的TypeScript类型如下:

// 用于类型专属字段的索引类型
interface RichTextMap {
  text?: { text: string };
  equation?: { equation: string };
  mention?: { mention: string };
}

// 带索引类型的主RichText接口
interface RichTextBase {
  type: "text" | "mention" | "equation";
  annotations: any;
  plain_text: string;
  href: string | null;
}

type RichText = RichTextBase & (RichTextMap[RichTextBase["type"]] & {});

符合该类型的示例对象:

const text = { 
  type: "text", 
  annotations: {},
  plain_text: "", 
  href: null, 
  text: { text: "" }
}

const mention = { 
  type: "mention", 
  annotations: {},
  plain_text: "", 
  href: null, 
  mention: { mention: "" }
}

你当前的方案创建了三个独立的Schema,需要手动判断使用场景,无法像RichText类型那样统一处理所有情况。

解决方案

使用discriminatedUnion基于type字段做鉴别,自动匹配对应的专属字段验证规则:

import { z } from "zod";

// 定义公共字段的基础Schema
const RichTextBaseSchema = z.object({
  type: z.enum(["text", "mention", "equation"]),
  annotations: z.object({}).passthrough(),
  plain_text: z.string(),
  href: z.string().url().nullable(),
});

// 为每个类型定义带固定type字面量的子Schema
const TextSchema = RichTextBaseSchema.extend({
  type: z.literal("text"),
  text: z.object({ text: z.string() }),
});

const MentionSchema = RichTextBaseSchema.extend({
  type: z.literal("mention"),
  mention: z.object({ mention: z.string() }),
});

const EquationSchema = RichTextBaseSchema.extend({
  type: z.literal("equation"),
  equation: z.object({ equation: z.string() }),
});

// 组合成单个鉴别联合Schema
const RichTextSchema = z.discriminatedUnion("type", [
  TextSchema,
  MentionSchema,
  EquationSchema,
]);

// 验证测试
RichTextSchema.parse(text); // 验证通过
RichTextSchema.parse(mention); // 验证通过
// 如果传入不符合的对象(比如type为text但带mention字段)会抛出验证错误

核心逻辑说明

  • discriminatedUnion是Zod专门处理鉴别联合类型的方法,它会根据指定的鉴别字段(这里是type)自动选择对应的验证规则
  • 每个子Schema通过extend将type固定为字面量值,确保Zod能精准匹配
  • 最终的RichTextSchema可以直接验证所有符合RichText类型定义的对象,无需额外分支判断

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 21:35:18