I think the comment mentioning recursive types is correct, but to fully illustrate what is intended, you can use z.lazy
, and then reference the schema from within its definition. Your example would become:
import { z } from "zod";
// Zod won't be able to infer the type because it is recursive.
// if you want to infer as much as possible you could consider using a
// base schema with the non-recursive fields and then a schema just for
// the recursive parts of your schema and use `z.union` to join then together.
interface IMediaResponse {
mediaId: number;
childMedias: IMediaResponse[];
}
const MediaResponseSchema: z.ZodType<IMediaResponse> = z.lazy(() =>
z.object({
mediaId: z.number(),
childMedias: z.array(MediaResponseSchema)
})
);
See the Zod Docs on GitHub although I think this should be equivalent to what was linked.
Just to respond to this comment:
What's the difference between that and copy-pasting the whole zod object?
One key difference is that this will recurse indefinitely. The childMedia
can be arbitrarily nested with their own child media. If you just copy and pasted then you end up with only one additional level of recursion and you are left with the same problem you started with when you try to decide what to put into the childMedias
that you pasted.