Zod array defines a schema for validating arrays where each element must conform to a specified type. It supports deep validation, custom constraints, and works seamlessly with nested schemas.
import { z } from 'zod';
const numbers = z.array(z.number());
The above example defines a Zod schema that validates an array of numbers. Each element in the array must be a number, and the entire array will fail validation if any item doesn’t meet that requirement.
Defining Arrays by Type: Zod Examples for Strings, Enums, and More
Zod makes it easy to validate arrays with strict type constraints. Whether you’re working with strings, numbers, enums, or nested schemas, Zod ensures every item in your array meets the expected shape.
Below are key array validation scenarios in Zod, each explained with targeted examples and guidance to help you apply them effectively.
Basic Types | Advanced Types |
---|---|
Zod array of Strings | Zod array of Files |
Zod array of Numbers | Zod array of Interface |
Zod array of Objects | Zod array of Multiple Types |
Zod array of Enums | Zod array of Images |
Zod array of Checkboxes | Zod array of Arrays |
Zod array of Literals | Zod array of Records |
Zod array of Emails | Zod array of Union |
Zod array of Integers | Zod array of Zod Objects |
Zod array of any | Zod array of Different Types |
Applying Constraints to Arrays: Min, Max, Length, and Non-Empty in Zod
Zod allows you to enforce precise constraints on arrays to control their length and content. Whether you’re ensuring a minimum number of items, restricting maximum length, or requiring non-empty arrays, Zod provides expressive methods to safeguard data shape and completeness.
In this section, we’ll cover how to apply .min()
, .max()
, .length()
, and .nonempty()
to array schemas with clear examples and practical applications.
Zod Array Not Empty
To ensure an array is not empty in Zod, use .nonempty()
. This guarantees that at least one item exists in the array at runtime.
z.array(z.string()).nonempty();
Zod Array (max) Maximum Length
Use .max(n)
to restrict the array to a maximum number of elements. If the array contains more than n
items, validation will fail.
z.array(z.string()).max(5);
Zod Array (min) Minimum Length
Use .min(n)
to ensure the array contains at least n
items. This is useful for enforcing required selections or inputs.
z.array(z.string()).min(2);
Zod Array of Fixed Length
To enforce a fixed array length, combine .min(n)
and .max(n)
with the same value.
z.array(z.string()).min(3).max(3);
Transforming and Refining Arrays: Using .transform(), .pipe(), and .refine()
Zod goes beyond static validation by offering tools to transform and refine array data dynamically. You can sanitize, compute, or reshape array inputs before or after validation using methods like .transform()
, .preprocess()
, .pipe()
, and .refine()
.
This section explores how to enhance array validation logic with transformation pipelines and custom rules using real-world use cases. These are the possible Zod array variations of transform, preprocess and refinement:
Zod Transform Array to String
Use .transform()
to convert an array into a string — often joined by a delimiter like a comma.
z.array(z.string()).transform(arr => arr.join(','))
Zod Transform Array to Object
You can use .transform()
to convert an array into an object, such as mapping array values to keys or indices.
z.array(z.string()).transform(arr =>
arr.reduce((acc, cur, idx) => {
acc[`key${idx}`] = cur;
return acc;
}, {} as Record<string, string>)
);
Zod Preprocess Array Example
Use z.preprocess()
to transform incoming data (e.g. strings, JSON, or raw values) before it reaches the array schema. This is useful when data isn’t in array form yet but should be.
z.preprocess(
(val) => (typeof val === 'string' ? val.split(',') : val),
z.array(z.string())
);
Zod Array Refine Path Example
Use .refine()
on an array schema to apply custom validation logic, and include the path
option to associate errors with specific parts of the array.
z.array(z.string()).refine(
(arr) => arr.includes("admin"),
{
message: "At least one value must be 'admin'",
path: ["0"], // optional: points to specific index/key
}
);
Making Arrays Optional, Nullable, or Default: Flexible Validation in Zod
Not all data is always present, and Zod supports flexible handling for optional, nullable, and defaultable arrays. You can allow undefined
, null
, or supply fallback values seamlessly using .optional()
, .nullable()
, .default()
, or .catch()
.
In this section, we’ll walk through how to create resilient schemas for optional or missing array inputs, along with scenarios where each method shines.
Zod Array of Objects Optional
You can define an optional array of objects in Zod by combining .array()
with .optional()
. This is useful when the array may or may not be present in the input, such as optional form sections or API fields.
const itemSchema = z.object({
name: z.string(),
price: z.number(),
});
z.array(itemSchema).optional()
Real World Examples: Shopping cart items, User addresses, Survey responses.
Zod Array Nullable
Zod allows arrays to be explicitly nullable using .nullable()
, meaning the value can either be an array or null
. This is useful for optional fields that may be reset or intentionally cleared in forms or APIs.
z.array(z.string()).nullable()
Real World Examples: Blog post tags, Delivery instructions, Product add-ons
Zod Array Empty Default Value
Use .default()
with z.array()
to provide a fallback when the field is missing or undefined. This is helpful in forms or APIs where the array should always exist, even if empty.
z.array(z.string()).default([])
Real World Examples: Cart items, Empty tags list, Uploaded files
Zod Array Catch
The .catch()
method in Zod sets a fallback value when parsing fails — useful for replacing invalid or malformed array inputs with a safe default.
z.array(z.string()).catch([])
Real World Examples: Applied coupons, Uploaded images
Conclusion
Zod’s array schema capabilities give you granular control over data structure, content, and behavior. From simple arrays of strings or numbers to complex nested objects with custom transformations and refinements, Zod ensures your array data is both valid and type-safe.
Whether you’re enforcing constraints like minimum length or fixed size, transforming arrays into other formats, or gracefully handling optional, nullable, or invalid inputs, Zod provides a declarative and expressive API to cover every use case. By applying these techniques, you can confidently validate real-world data scenarios such as form submissions, API payloads, user inputs, and application state.
By mastering Zod arrays, you’re building more predictable and safer applications — with minimal runtime surprises and maximum developer clarity.