z.enum()
breaks if you pass it an actual enum or array created by destructuring enum using Object.values()`
#2125
-
This can't possibly be how Zod is designed to handle enum validation... I would have thought this would work: import { z } from 'zod';
enum PizzaType {
Canadian = 'Canadian',
Cheese = 'Cheese',
Hawaiian = 'Hawaiian',
MeatLovers = 'Meat Lovers',
Pepperoni = 'Pepperoni',
Vegetarian = 'Vegetarian',
}
const orderSchema = z.object({
id: z.number(),
type: z.enum(PizzaType)
})
const order = {
id: 1,
type: 'Canadian'
}
orderSchema.safeParse(order) Looks good to me. Logical. Simple. Should definitely work. Right? error TS2769: No overload matches this call.
Overload 1 of 2, '(values: readonly [string, ...string[]], params?: RawCreateParams): ZodEnum<[string, ...string[]]>', gave the following error.
Argument of type 'typeof PizzaType' is not assignable to parameter of type 'readonly [string, ...string[]]'.
Overload 2 of 2, '(values: [string, ...string[]], params?: RawCreateParams): ZodEnum<[string, ...string[]]>', gave the following error.
Argument of type 'typeof PizzaType' is not assignable to parameter of type '[string, ...string[]]'.
34 .enum(PizzaType)
~~~~~~~ Okay, well that's weird. I guess I'll just do const orderSchema = z.object({
id: z.number(),
type: z.enum(Object.values(PizzaType))
}) error TS2769: No overload matches this call.
Overload 1 of 2, '(values: readonly [string, ...string[]], params?: RawCreateParams): ZodEnum<[string, ...string[]]>', gave the following error.
Argument of type 'typeof PizzaType' is not assignable to parameter of type 'readonly [string, ...string[]]'.
Overload 2 of 2, '(values: [string, ...string[]], params?: RawCreateParams): ZodEnum<[string, ...string[]]>', gave the following error.
Argument of type 'typeof PizzaType' is not assignable to parameter of type '[string, ...string[]]'.
34 .enum(Object.values(PizzaType))
~~~~~~~~~~~~~~~~~ Uh, okay... How about destructuring into a new array of strings. const orderSchema = z.object({
id: z.number(),
type: z.enum([...Object.values(PizzaType)])
}) error TS2769: No overload matches this call.
Overload 1 of 2, '(values: readonly [string, ...string[]], params?: RawCreateParams): ZodEnum<[string, ...string[]]>', gave the following error.
Argument of type 'typeof PizzaType' is not assignable to parameter of type 'readonly [string, ...string[]]'.
Overload 2 of 2, '(values: [string, ...string[]], params?: RawCreateParams): ZodEnum<[string, ...string[]]>', gave the following error.
Argument of type 'typeof PizzaType' is not assignable to parameter of type '[string, ...string[]]'.
34 .enum([...Object.values(PizzaType)])
~~~~~~~~~~~~~~~~~ Okay, well, I don't know how much uglier I need to get... I mean this would be even uglier, but I guess I could try: const orderSchema = z.object({
id: z.number(),
type: z.enum([
PizzaType.Canadian,
PizzaType.Cheese,
PizzaType.Hawaiian,
PizzaType.MeatLovers,
PizzaType.Pepperoni,
PizzaType.Vegetarian,
]
}) ✅ Yup! Looks good to me! WHY, ZOD!? WHY!? 😭 |
Beta Was this translation helpful? Give feedback.
Replies: 6 comments 9 replies
-
Is this what you are looking for? enum PizzaType {
Canadian = 'Canadian',
Cheese = 'Cheese',
Hawaiian = 'Hawaiian',
MeatLovers = 'Meat Lovers',
Pepperoni = 'Pepperoni',
Vegetarian = 'Vegetarian',
}
const orderSchema = z.object( {
id: z.number(),
type: z.nativeEnum( PizzaType )
} )
const order = {
id: 1,
type: 'Canadian'
}
orderSchema.safeParse( order ) Other Resources: If you found my answer satisfactory, please consider supporting me. Even a small amount is greatly appreciated. Thanks friend! 🙏 |
Beta Was this translation helpful? Give feedback.
-
Would it not make more sense to have |
Beta Was this translation helpful? Give feedback.
-
Before making a bold statement based on videos that try to attract attention with catchy titles, consider at least reading the comments. You will notice that many people disagree with the downsides described in those videos because they are often exaggerated or pulled out of thin air. |
Beta Was this translation helpful? Give feedback.
-
So, let me get this straight: I can do This makes zero sense. I have a bunch of SSOT JSON lists which I though I could just push as enums. |
Beta Was this translation helpful? Give feedback.
-
I've created a utility function to enhance the type safety of Zod enums. The const zodEnum = <T>(arr: T[]): [T, ...T[]] => arr as [T, ...T[]]; Now, you can use this function to satisfy Zod's enum typization. For example, let's say you have a type 'UserType' and array with it: type UserType = 'admin' | 'user';
const userTypes = ['admin', 'user'] satisfies UserType[]; By applying the // With error
z.enum(userTypes);
// Without error
z.enum(zodEnum(userTypes)); Or you can validate it: z.enum(zodEnum<UserType>(['admin', 'user'])); |
Beta Was this translation helpful? Give feedback.
-
I've tried like below |
Beta Was this translation helpful? Give feedback.
Is this what you are looking for?
https://github.com/colinhacks/zod#native-enums
Other Resources:
https://gist.github.com/JacobWeisenburger/1c72eda9e823cd6caed327db470f0613
If you found my answer satisfactory, please consider supporting me. Even a small amount is greatly appreciated. Thanks friend! 🙏
https://github.com/sponsors/Jac…