typescript - Definere gjensidig rekursive zod-skjemaer
Jeg er ny til TypeScript og jeg får en feil i følgende kode:
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)
});
Feilen er enkel å forstå... fordi variablene er avhengige av hverandre.
ReferenceError: Cannot access 'SpatialPlacement' before initialization
Hvis jeg bytter om på de ovennevnte variablene, altså hvis jeg skriver SpatialPlacement først og deretter SpatialEntity, er feilen fortsatt den samme.
Noen idé om hvordan man kan løse dette?? Enhver ledetråd ville bli satt pris på. Takk!
Svar #1
Problemet på overflaten er at du forsøker å referere til en verdi før dens definisjon. Kjernen i problemet er at dette skjemaet er gjensidig rekursivt, så på et visst nivå vil du trenge z.lazy.
Jeg prøvde å forenkle problemet litt. Et problem med rekursive typer i zod er at du vanligvis må spesifisere typene eksplisitt fordi zod ikke kan slutte seg til hva typene bør være.
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
});
De to tingene dette gjør er:
- Det gjør
SpatialEntitytilgjengelig forSpatialPlacementved å definere verdien som enlet. Dette lar oss utsette implementeringen av skjemaet for denne enheten, men gjør navnet til en del av omfanget forSpatialPlacement. - Skjemaet
SpatialPlacementbrukerz.lazyfor å utsette løsning av skjemaet forSpatialEntity. Hvis det forsøkte å bruke verdien avSpatialEntityutenz.lazy, ville verdien fortsatt væreundefined, og ting ville ikke fungere som forventet. (Prøv å fjernez.lazy; TypeScript vil klage)
