如何解决Zod递归Schema定义中的隐式any类型错误?
Zod 循环引用 Schema 类型注解错误解决
问题场景
编写了以下 Zod Schema 代码:
export const ActionTypeValidator = z.object({ action: z.any(), state: z.any(), actionGroups: z.array(ActionGroupTypeValidator).optional(), }) export type ActionType = z.infer<typeof ActionTypeValidator> export const ActionGroupTypeValidator = z.object({ id: z.string(), name: z.string(), actions: z.array(ActionTypeValidator), }) export type ActionGroupType = z.infer<typeof ActionGroupTypeValidator>
出现两个 Vue 类型报错:
- ActionTypeValidator 隐式具有any类型,因其无类型注解且在自身初始化中被直接或间接引用。
- ActionGroupTypeValidator 存在同样的错误。
尝试过使用 z.lazy 但未解决,寻求解决办法。
解决方法
错误根源是两个Schema存在循环引用,TypeScript初始化阶段无法解析相互依赖的类型,加上缺少明确类型注解导致隐式any报错。正确结合z.lazy和类型注解即可解决,以下是两种可行方案:
方案一:提前声明类型并配合z.lazy
import { z } from 'zod'; // 提前导出类型,用 ZodType 约束 validator export type ActionType = z.infer<typeof ActionTypeValidator>; export type ActionGroupType = z.infer<typeof ActionGroupTypeValidator>; // 给 validator 添加明确类型注解,并用 z.lazy 延迟引用对方 export const ActionTypeValidator: z.ZodType<ActionType> = z.object({ action: z.any(), state: z.any(), actionGroups: z.array(z.lazy(() => ActionGroupTypeValidator)).optional(), }); export const ActionGroupTypeValidator: z.ZodType<ActionGroupType> = z.object({ id: z.string(), name: z.string(), actions: z.array(z.lazy(() => ActionTypeValidator)), });
方案二:先声明变量再赋值
import { z } from 'zod'; // 先声明变量并指定类型,规避初始化时的引用冲突 export let ActionTypeValidator: z.ZodObject<{ action: z.ZodAny; state: z.ZodAny; actionGroups: z.ZodOptional<z.ZodArray<typeof ActionGroupTypeValidator>>; }>; export let ActionGroupTypeValidator: z.ZodObject<{ id: z.ZodString; name: z.ZodString; actions: z.ZodArray<typeof ActionTypeValidator>; }>; // 赋值阶段用 z.lazy 处理循环引用 ActionTypeValidator = z.object({ action: z.any(), state: z.any(), actionGroups: z.array(z.lazy(() => ActionGroupTypeValidator)).optional(), }); ActionGroupTypeValidator = z.object({ id: z.string(), name: z.string(), actions: z.array(z.lazy(() => ActionTypeValidator)), }); // 导出推导后的类型 export type ActionType = z.infer<typeof ActionTypeValidator>; export type ActionGroupType = z.infer<typeof ActionGroupTypeValidator>;
关键注意点
z.lazy(() => 目标Validator)用于延迟获取引用,避免初始化时的循环依赖问题,必须用箭头函数包裹,不能直接传入Validator变量。- 必须给每个Validator添加明确的类型注解,让TypeScript提前推断类型,消除隐式any的报错。
内容的提问来源于stack exchange,提问作者MrSpt
相关产品推荐
相关产品推荐

