我是 TypeScript 新手,在以下代码中遇到错误:
import { z } from "zod";
export const SpatialEntity = z.object({
dimension_units: z.string().optional(),
placement: SpatialPlacement
});
export const SpatialPlacement = SpatialPlacementCommon.extend({
source: z.string().or(SpatialEntity).optional(),
target: z.string().or(SpatialEntity)
});
错误是直接的......因为变量是相互依赖的。
ReferenceError: Cannot access 'SpatialPlacement' before initialization
如果我交换上述变量,即如果我先写 SpatialPlacement
然后写 SpatialEntity
那么错误也是相同的。
知道如何解决这个问题吗?任何线索将不胜感激。谢谢!
最佳答案
锡上的问题是您试图在定义之前引用一个值。问题的核心是该模式是相互递归的,因此在某种程度上您将需要 z.lazy
.
我试图稍微简化问题。 zod 中递归类型的一个问题是,您通常需要显式指定类型,因为 zod 无法推断类型应该是什么。
import { z } from "zod";
interface ISpacialEntity {
dimension_units?: string;
placement: ISpacialPlacement;
}
interface ISpacialPlacement {
source?: string | ISpacialEntity;
target: string | ISpacialEntity;
}
let SpatialEntity: z.ZodType<ISpacialEntity>;
export const SpatialPlacement: z.ZodType<ISpacialPlacement> = z.object({
source: z.lazy(() => z.string().or(SpatialEntity).optional()),
target: z.lazy(() => z.string().or(SpatialEntity))
});
SpatialEntity = z.object({
dimension_units: z.string().optional(),
placement: SpatialPlacement
});
它所做的两件事是:
- 通过将值定义为
let
,使SpatialEntity
可用于SpatialPlacement
。这让我们可以推迟实现该实体的架构,但使名称成为SpatialPlacement
范围的一部分。 SpatialPlacement
架构使用z.lazy
来推迟解析SpatialEntity
的架构。如果它尝试在没有z.lazy
的情况下使用SpatialEntity
的值,那么该值仍然是undefined
并且事情不会按预期工作。 (尝试删除z.lazy
; typescript 会提示)
关于typescript - 定义相互递归的 zod 模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76069429/