Reputation: 7573
New to Typescript, Zod & Trpc.
Say I have a schema for both animals & plants. I want to store all their common properties in the "root" of the schema and then put the more specific properties into a sub-object called custom
. (just a made-up example to simplify things)
So far I have this:
create: t.procedure
.input(z.object({
id: z.string(),
type: z.string(), //can be "ANIMAL" or "PLANT"
//all other common properties go here
//...
custom: z.object({ fur: z.string() }) //...if it's an animal, it will have "fur" here, if it's a plant something entirely different, like "seeds"
}).nullish())
I don't understand how to get this to work, or how I would accomplish this with zod. I looked into zods discriminated union, but I don't seem to fully understand how the syntax works?
Upvotes: 2
Views: 6403
Reputation: 10006
This is a good example of when you would use discriminatedUnion
.
For example:
const inputSchema = z.discriminatedUnion("type", [
z.object({
id: z.string(),
type: z.literal('ANIMAL'),
custom: z.object({ fur: z.string() }),
}),
z.object({
id: z.string(),
type: z.literal('PLANT'),
custom: z.object({ seeds: z.number() }),
})
]).nullish();
You could then pass that schema into input()
. If you have a lot of shared fields, you could store those in a base schema which you would merge
in once rather than duplicating them in each branch.
Upvotes: 1