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

如何在Zod中创建多级菜单递归Schema?

解决Zod递归多级菜单Schema的字段限制问题

直接给你能严格限制字段的递归实现,核心是用z.lazy()处理递归,同时通过.strict()禁用额外字段:

import { z } from "zod";

// 递归定义菜单项Schema
const MenuItemSchema = z.object({
  // 必选的标题字段
  title: z.string(),
  // 可选的跳转链接(一级菜单项用)
  url: z.string().optional(),
  // 可选的子菜单数组,用lazy实现递归引用
  items: z.lazy(() => z.array(MenuItemSchema)).optional(),
}).strict(); // 关键:strict() 只允许定义的三个字段,多余字段直接报错

// 根菜单Schema(如果你的CMS返回单个菜单项而非数组,直接用MenuItemSchema即可)
const MenuSchema = z.array(MenuItemSchema);

关键说明

  • z.lazy():延迟Schema的求值,解决递归引用时的"未定义"问题,是Zod处理递归结构的标准方式
  • .strict():强制Zod验证时拒绝任何未在Schema中声明的字段,彻底解决"允许额外键"的问题
  • 字段可选性:url和items设为可选,适配两种常见场景:
    • 叶子菜单项:仅包含title + url
    • 父菜单项:仅包含title + items

验证测试示例

// 合法的多级菜单
const validMenu = [
  { title: "首页", url: "/" },
  {
    title: "文档",
    items: [
      { title: "快速开始", url: "/docs/quickstart" },
      { title: "API参考", url: "/docs/api" }
    ]
  }
];

MenuSchema.parse(validMenu); // 验证通过

// 带非法额外字段的菜单
const invalidMenu = [
  { title: "关于", url: "/about", hidden: true } // hidden是未定义的字段
];

MenuSchema.parse(invalidMenu); // 抛出ZodError,提示"Unknown key(s) in object: 'hidden'"

内容的提问来源于stack exchange,提问作者G.Rose

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 23:18:30