zod
zod copied to clipboard
Recursive schema
Hello,
I'm currently experiencing a problem that I can't solve.
I have a recursion problem between two schemas and I don't understand how to do it.
My first schema OrderResponseSchema:
export const OrderSchema = z.object({
[...]
account: CustomerSchema,
[...]
});
export type OrderResponse = z.infer<typeof OrderResponseSchema>
export const OrderResponseSchema = z.object({
count: z.number(),
page_count: z.number(),
page: z.number(),
results: z.array(OrderSchema)
})
And my second CustomerSchema which extends the OrderResponseSchema in the orders object:
import { OrderResponseSchema } from "./Order";
import { z } from 'zod';
export type Customer = z.infer<typeof CustomerSchema>
export const CustomerSchema = z.object({
[...]
orders: z.optional(OrderResponseSchema),
});
This is the error I'm encountering:
'CustomerSchema' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.ts(7022)
const CustomerSchema: any
This error disappears if I comment out the orders object.
Thanks for your help
Versions:
"typescript": "5.1.3",
"zod": "^3.22.4"
So what I guess is happening is an infinite loop where you try to get 1 schema for customer that has orders and 1 schema for orders that have accounts. However, they are linked so it will just keep linking.
Instead make schemas without the linked properties (eg: CustomerSchema without orders) and use that as schema for your order accounts, same for the OrderSchema in orders, remove the linked items.
If you want to use these linked properties, I suggest to do something like this:
typscriptlang.org/play#code/...
You will see the exact error you get once you change the Order to OrderWithAccount and Customer to CustomerWithOrder.
There are docs here on how to properly define recursive types: https://github.com/colinhacks/zod?tab=readme-ov-file#recursive-types
I'm afraid this is a little onerous at the moment and does require an explicit type annotation. This will hopefully not be necessary in Zod 4.