You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Given multiple different implementations of a shared base, e.g. Foo and Bar I want to define schemas for them.
But I also want to define a discriminated union schema for those types which requires a common field to identify each one of them.
My first approach
When defining a new schema you have to keep in mind that the field "type" must exist which is not ideal
const baseSchema = z.object({
id: z.string(),
// ... other base fields ...
});
const fooSchema = baseSchema.extend({
type: z.literal('foo'),
// ... other foo fields ...
});
const barSchema = baseSchema.extend({
type: z.literal('bar'),
// ... other bar fields ...
});
const itemSchema = z.discriminatedUnion('type', [fooSchema, barSchema]);
My second approach
Use a function to "inject" the dynamic parameters. But now it's not possible to infer a base type because it's a function expecting parameters.
function createBaseItemSchema(type: string) {
return z.object({
id: z.string(),
type: z.literal(type),
// ... other base fields ...
});
}
const fooSchema = createBaseItemSchema('foo').extend({
// ... other foo fields ...
});
const barSchema = createBaseItemSchema('bar').extend({
// ... other bar fields ...
});
const itemSchema = z.discriminatedUnion('type', [fooSchema, barSchema]);
My third approach
Maybe I don't even need the type field? Maybe Zod / TypeScript is able to deal with the discriminated union by inspecting the whole schema? So go for the first approach and just leave the type field.
But which key should I pass to the discriminatedUnion schema then?
Having a type field with an exact value would make it easy to setup type guard functions.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Given multiple different implementations of a shared base, e.g.
Foo
andBar
I want to define schemas for them.But I also want to define a discriminated union schema for those types which requires a common field to identify each one of them.
My first approach
When defining a new schema you have to keep in mind that the field "type" must exist which is not ideal
My second approach
Use a function to "inject" the dynamic parameters. But now it's not possible to infer a base type because it's a function expecting parameters.
My third approach
Maybe I don't even need the
type
field? Maybe Zod / TypeScript is able to deal with the discriminated union by inspecting the whole schema? So go for the first approach and just leave thetype
field.But which key should I pass to the
discriminatedUnion
schema then?Having a
type
field with an exact value would make it easy to setup type guard functions.How would you solve this?
Beta Was this translation helpful? Give feedback.
All reactions