Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Merge of two enums zod

Tags:

zod

I have 2 enums, const Option1 = z.enum(["option1"]) and const Option2 = z.enum(["option2"]). I want to merge these two into z.ZodEnum<["option1", "option2"]>

The only way I came up with so far is

export const Options = z.enum([
  ...Option1.options,
  ...Option2.options,
]);
// Options.options is now ["option1", "option2"]

Is there any zod native way to do this?

like image 806
Gabriel Petersson Avatar asked Oct 18 '25 15:10

Gabriel Petersson


2 Answers

the issue you're facing here is due to the type of the combined options.

const allOptions = [...Option1.options, ...Option2.options]

the inferred type of allOptions in this case is: ("option1" | "option2")[] and zod can't create an enum out of that.

however, if you define allOptions like this:

const allOptions = [...Option1.options, ...Option2.options] as const

then the inferred type of allOptions will be the tuple ["option1", "option2"] which is exactly what you want.

so, putting that all together, to combine the options, you'd say:

const Options = z.enum([...Option1.options, ...Option2.options] as const)

and the inferred type of Options will be z.ZodEnum<["option1", "option2"]>

like image 154
mizerlou Avatar answered Oct 22 '25 05:10

mizerlou


There's an extension of @mizerlou's answer for nativeEnum.

Similar to

const allOptions = [...Option1.options, ...Option2.options] as const

You have to do

const Options = { ...Option1, ...Option2 } as const;

Something like this

const Option1 = { OPTION1: 'Option1' } as const;
const Option1Enum = z.nativeEnum(Option1);
type Option1 = z.infer<typeof Option1Enum>;

const Option2 = { OPTION2: 'Option2' } as const;
const Option2Enum = z.nativeEnum(Option2);
type Option2 = z.infer<typeof Option2Enum>;

const Options = { ...Option1, ...Option2 } as const;
const OptionsEnum = z.nativeEnum(Options);
type Options = z.infer<typeof OptionsEnum>;
like image 25
icc97 Avatar answered Oct 22 '25 07:10

icc97