Replies: 1 comment
-
I don't think there's a straightforward way to do this. The closest to the basic TS types is const eitherAOrBSchema = z.union([
z.object({
a: z.string(),
b: z.never(),
}),
z.object({
a: z.never(),
b: z.number(),
}),
]);
/*
type Type = {
a: string;
b: never;
} | {
a: never;
b: number;
}
*/
type Type = z.input<typeof eitherAOrBSchema>; However, this doesn't work because the type that is The other alternative is like this, which doesn't work either. const eitherAOrBSchema = z.union([
z.object({
a: z.string(),
b: z.never().optional(),
}),
z.object({
a: z.never().optional(),
b: z.number(),
}),
]);
/*
type Type = {
a: string;
b?: undefined;
} | {
a?: undefined;
b: number;
}
*/
type Type = z.input<typeof eitherAOrBSchema>; As mentioned in #3186, Zod doesn't differentiate between optional properties and properties that should be undefined. I think the only solution right now is to use the type EitherAOrB =
{
a: string;
b?: never;
} | {
a?: never;
b: number;
};
const eitherAOrBSchema = z
.object({
a: z.string().optional(),
b: z.number().optional(),
})
.superRefine((data, ctx): data is EitherAOrB => {
if ("a" in data && "b" in data) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "Either a or b can be defined, but not both.",
});
} else if (!("a" in data || "b" in data)) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "Either a or b must be defined.",
});
}
});
type InputType = z.input<typeof eitherAOrBSchema>;
type OutputType = z.output<typeof eitherAOrBSchema>; |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
In TypeScript I can create an XOR type using a union type like
This allows me to have types where when e.g.
a
is set, I am not allowed to also setb
.I tried to do this with zod:
However, like this, TypeScript doesn't care if I set both properties on an EitherAOrB.
I found this discussion where a solution for parsing was found, however this does not deal with inferring a type.
Is this possible to achieve?
Beta Was this translation helpful? Give feedback.
All reactions