Basic Usage
Create an array schema that validates each element.
import { z } from 'zod';
const StringArray = z.array(z.string());
StringArray.parse(['a', 'b', 'c']); // ✓ Valid
StringArray.parse(['a', 1, 'c']); // ✗ Invalid - contains number
type StringArray = z.infer<typeof StringArray>;
// string[]
Signature
function array<T extends SomeType>(
element: T,
params?: string | ZodArrayParams
): ZodArray<T>
The schema to validate each array element against.
Optional error message (string) or configuration object.
Properties
Access the element schema.const schema = z.array(z.string());
schema.element; // ZodString
Methods
min()
Set a minimum length for the array.
const AtLeastThree = z.array(z.string()).min(3);
AtLeastThree.parse(['a', 'b', 'c']); // ✓ Valid
AtLeastThree.parse(['a', 'b']); // ✗ Invalid - too short
AtLeastThree.parse(['a', 'b', 'c', 'd']); // ✓ Valid
Signature:
min(minLength: number, params?: string | ZodCheckMinLengthParams): this
Minimum number of elements required.
Optional error message or configuration object.z.array(z.string()).min(3, 'At least 3 items required')
z.array(z.string()).min(3, { message: 'Too few items' })
max()
Set a maximum length for the array.
const AtMostFive = z.array(z.number()).max(5);
AtMostFive.parse([1, 2, 3]); // ✓ Valid
AtMostFive.parse([1, 2, 3, 4, 5]); // ✓ Valid
AtMostFive.parse([1, 2, 3, 4, 5, 6]); // ✗ Invalid - too long
Signature:
max(maxLength: number, params?: string | ZodCheckMaxLengthParams): this
Maximum number of elements allowed.
Optional error message or configuration object.z.array(z.number()).max(5, 'Too many items')
z.array(z.number()).max(5, { message: 'Maximum 5 items' })
length()
Set an exact length for the array.
const ExactlyThree = z.array(z.boolean()).length(3);
ExactlyThree.parse([true, false, true]); // ✓ Valid
ExactlyThree.parse([true, false]); // ✗ Invalid - wrong length
ExactlyThree.parse([true, false, true, false]); // ✗ Invalid - wrong length
Signature:
length(len: number, params?: string | ZodCheckLengthEqualsParams): this
Exact number of elements required.
Optional error message or configuration object.z.array(z.boolean()).length(3, 'Must have exactly 3 items')
nonempty()
Require at least one element (equivalent to .min(1)).
const NonEmptyArray = z.array(z.string()).nonempty();
NonEmptyArray.parse(['item']); // ✓ Valid
NonEmptyArray.parse([]); // ✗ Invalid - empty array
type NonEmptyArray = z.infer<typeof NonEmptyArray>;
// [string, ...string[]]
The inferred type becomes a tuple type [T, ...T[]] to ensure at least one element at the type level.
Signature:
nonempty(params?: string | ZodCheckMinLengthParams): this
Optional error message or configuration object.z.array(z.string()).nonempty('Array cannot be empty')
unwrap()
Access the element schema.
const StringArray = z.array(z.string());
const ElementSchema = StringArray.unwrap();
type Element = z.infer<typeof ElementSchema>;
// string
Signature:
Combining Validations
You can chain multiple validation methods:
const BoundedArray = z.array(z.number())
.min(2, 'Need at least 2 numbers')
.max(10, 'Cannot exceed 10 numbers');
BoundedArray.parse([1, 2, 3]); // ✓ Valid
BoundedArray.parse([1]); // ✗ Invalid - too short
BoundedArray.parse([...Array(11).fill(0)]); // ✗ Invalid - too long
Complex Element Types
Arrays can contain any Zod schema:
Objects
const Users = z.array(
z.object({
id: z.string(),
name: z.string(),
email: z.string().email(),
})
);
type Users = z.infer<typeof Users>;
// Array<{ id: string; name: string; email: string }>
Nested Arrays
const Matrix = z.array(z.array(z.number()));
type Matrix = z.infer<typeof Matrix>;
// number[][]
Matrix.parse([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]); // ✓ Valid
Unions
const MixedArray = z.array(z.union([z.string(), z.number()]));
type MixedArray = z.infer<typeof MixedArray>;
// (string | number)[]
MixedArray.parse(['a', 1, 'b', 2]); // ✓ Valid
Convenience Method
You can also create arrays using the .array() method on any schema:
const StringArray = z.string().array();
// Equivalent to: z.array(z.string())
const MinThreeStrings = z.string().array().min(3);
// Equivalent to: z.array(z.string()).min(3)
Type Inference
const schema = z.array(z.string()).min(1).max(10);
type Output = z.infer<typeof schema>;
// string[] (with runtime validation for 1-10 elements)
type Input = z.input<typeof schema>;
// string[] (same as output for arrays without transformations)
Refinements
Add custom validation logic:
const UniqueNumbers = z.array(z.number())
.refine(
(arr) => new Set(arr).size === arr.length,
'Array must contain unique values'
);
UniqueNumbers.parse([1, 2, 3]); // ✓ Valid
UniqueNumbers.parse([1, 2, 2, 3]); // ✗ Invalid - duplicate values
const SortedArray = z.array(z.number())
.min(2)
.refine(
(arr) => arr.every((val, i, a) => i === 0 || val >= a[i - 1]),
'Array must be sorted in ascending order'
);
SortedArray.parse([1, 2, 3, 4]); // ✓ Valid
SortedArray.parse([1, 3, 2, 4]); // ✗ Invalid - not sorted
- z.tuple() - For fixed-length arrays with specific types
- z.set() - For sets with unique values
- z.record() - For key-value collections