Zod递归Schema构建:含特殊叶子节点的树形结构报错unrecognized_keys
Zod 树形节点类型的正确实现方案
需求说明
需要在Zod中实现以下TypeScript树形结构类型:
type CommonParentData = { id: string, name: string, // 其他公共属性... } type SpecificChild = CommonParentData & { specific_property1: string specific_property2: number children: [] } type Parent = CommonParentData & { children: Array<CommonParentData | SpecificChild> }
该结构中,所有节点共享公共属性,仅叶子节点拥有专属额外属性,且叶子节点的children为空数组。
问题重现
之前的实现尝试中,出现**无法识别的键(unrecognized_keys)**错误,原因是递归schema仅基于公共属性扩展,未包含叶子节点的专属属性,且使用strictObject时会拦截未定义的额外字段。原尝试代码:
const commonSchema = z.strictObject({ id: z.string(), name: z.string(), // 其他公共属性... }); const childSchema = commonSchema.merge( z.strictObject({ specific_property1: z.string(), specific_property2: z.number(), children: z.tuple([]), }), ); type Child = z.infer<typeof childSchema>; type Parent = z.infer<typeof commonSchema> & { children: Array<Child | Parent>; }; const schema: z.ZodType<Parent> = commonSchema.extend({ children: z.lazy(() => schema.array()), });
正确实现方案
通过**联合类型(Union)**将父节点与叶子节点的schema合并,利用Zod的自动类型匹配能力处理递归结构,同时保留严格校验规则:
import { z } from "zod"; // 定义公共字段的基础schema const commonFields = z.object({ id: z.string(), name: z.string(), // 补充其他公共属性 }); // 叶子节点schema:公共字段 + 专属属性 + 空children元组 const leafNodeSchema = commonFields.merge( z.strictObject({ specific_property1: z.string(), specific_property2: z.number(), children: z.tuple([]), }) ); // 先声明递归节点的类型引用 type TreeNode = z.infer<typeof nodeSchema>; // 父节点schema:公共字段 + 子节点数组(支持递归的节点类型) const parentNodeSchema = commonFields.merge( z.strictObject({ children: z.lazy(() => nodeSchema.array()), }) ); // 节点联合schema:同时支持父节点和叶子节点 const nodeSchema = z.union([parentNodeSchema, leafNodeSchema]); // 导出对应的TypeScript类型 type LeafNode = z.infer<typeof leafNodeSchema>; type ParentNode = z.infer<typeof parentNodeSchema>;
关键说明
- 联合类型匹配:Zod会根据
children字段的类型(空元组 vs 节点数组)自动匹配对应的schema,不会触发额外字段错误。 - 递归处理:使用
z.lazy()延迟引用nodeSchema,解决递归类型的定义顺序问题。 - 严格模式保留:叶子节点和父节点单独使用
strictObject,确保各自字段的严格校验,同时联合类型的匹配逻辑会避免跨类型的字段校验冲突。
内容的提问来源于stack exchange,提问作者WTP000
相关产品推荐
相关产品推荐

