- Published on
Does zod have something equivalent to yup's oneOf() ?
- Authors
- Name
- Ripal & Zalak
Zod Equivalent to Yup's oneOf Method
When using Zod for schema validation, developers often look for an equivalent to Yup's oneOf()
method, which allows specifying a list of accepted values for a property. In this post, we'll explore how to achieve the same functionality in Zod efficiently.
The Yup Approach
In Yup, you can easily limit a property to specific values using oneOf
:
prop: Yup.string().oneOf(['value1', 'value2', 'value3'])
Achieving the Same in Zod
While Zod does not have a direct oneOf
method, it provides multiple ways to implement this functionality.
z.union
with z.literal
1. Using You can combine z.literal
values using z.union
to define a schema with specific accepted values:
import { z } from 'zod'
const schema = z.object({
prop: z.union([z.literal('value1'), z.literal('value2'), z.literal('value3')]),
})
This approach has the added benefit of inferring the exact type of the property, such as:
prop: 'value1' | 'value2' | 'value3'
2. Creating a Helper Function
To reduce boilerplate, you can write a utility function that simplifies the creation of z.union
schemas:
import { z } from 'zod'
function oneOf<T extends string | number | boolean | bigint | null | undefined>(
values: readonly [T, T, ...T[]]
) {
return z.union(values.map((value) => z.literal(value)) as [z.ZodLiteral<T>, ...z.ZodLiteral<T>[]])
}
const schema = z.object({
prop: oneOf(['value1', 'value2', 'value3'] as const),
})
z.enum
3. Using If your accepted values are strings, Zod's z.enum
is the most concise and type-safe approach:
const schema = z.object({
prop: z.enum(['value1', 'value2', 'value3']),
})
This method is both readable and efficient, and it automatically infers the type as:
prop: 'value1' | 'value2' | 'value3'
Comparison of Methods
Method | Best Use Case | Example Values |
---|---|---|
z.union + z.literal | Mixed data types (e.g., strings, numbers) | [5, 10, 15] |
Helper Function | Reusable logic for multiple schemas | ["A", "B", "C"] |
z.enum | String-only values | ["yes", "no"] |
FAQs
Can Zod handle dynamic values for validation?
Zod works best with statically defined schemas. For dynamic validations, you can use z.custom
or superRefine
for more complex logic.
Which method is most type-safe?
Using z.enum
or z.union
with z.literal
ensures strict type safety in TypeScript.
Can I validate against a large list of values?
For a large list of allowed values, consider using a helper function or z.custom
with dynamic logic to improve maintainability.