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

如何解决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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 07:20:13