如何在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
相关产品推荐
相关产品推荐

