0
# Collection Schemas
1
2
Validators for arrays, objects, tuples, maps, sets, records, enums, and literals with full type inference.
3
4
## Array
5
6
```typescript { .api }
7
/**
8
* Create an array validation schema with element type validation
9
* @param element - Schema for array elements
10
* @param params - Optional configuration with description and error map
11
* @returns ZodArray schema instance
12
*/
13
function array<T extends ZodTypeAny>(
14
element: T,
15
params?: { description?: string; errorMap?: ZodErrorMap }
16
): ZodArray<T>;
17
18
interface ZodArray<T extends ZodTypeAny> extends ZodType<
19
Array<z.infer<T>>,
20
Array<z.input<T>>
21
> {
22
/** Minimum array length */
23
min(size: number, msg?: string | { message?: string }): this;
24
/** Maximum array length */
25
max(size: number, msg?: string | { message?: string }): this;
26
/** Exact array length */
27
length(size: number, msg?: string | { message?: string }): this;
28
/** Non-empty array (min length 1) */
29
nonempty(msg?: string | { message?: string }): this;
30
/** Get element schema */
31
element: T;
32
}
33
```
34
35
**Examples:**
36
```typescript
37
// Basic array
38
const StringArraySchema = z.array(z.string());
39
StringArraySchema.parse(["hello", "world"]); // Valid
40
41
// Array with constraints
42
const LimitedArraySchema = z.array(z.number()).min(1).max(10);
43
44
// Non-empty array
45
const NonEmptySchema = z.array(z.string()).nonempty();
46
47
// Nested arrays
48
const MatrixSchema = z.array(z.array(z.number()));
49
50
// Array of objects
51
const UsersSchema = z.array(
52
z.object({
53
name: z.string(),
54
age: z.number(),
55
})
56
);
57
```
58
59
## Object
60
61
```typescript { .api }
62
/**
63
* Create an object validation schema with property schemas
64
* @param shape - Record of property schemas
65
* @param params - Optional configuration with description and error map
66
* @returns ZodObject schema instance
67
*/
68
function object<T extends ZodRawShape>(
69
shape: T,
70
params?: { description?: string; errorMap?: ZodErrorMap }
71
): ZodObject<T>;
72
73
/**
74
* Create a strict object schema (rejects extra properties)
75
* @param shape - Record of property schemas
76
* @returns ZodObject in strict mode
77
*/
78
function strictObject<T extends ZodRawShape>(shape: T): ZodObject<T>;
79
80
/**
81
* Create a loose object schema (passes through extra properties)
82
* @param shape - Record of property schemas
83
* @returns ZodObject in passthrough mode
84
*/
85
function looseObject<T extends ZodRawShape>(shape: T): ZodObject<T>;
86
87
interface ZodObject<T extends ZodRawShape> extends ZodType<
88
{ [K in keyof T]: z.infer<T[K]> },
89
{ [K in keyof T]: z.input<T[K]> }
90
> {
91
/** Property schemas */
92
shape: T;
93
94
/** Get enum of object keys */
95
keyof(): ZodEnum<[keyof T, ...(keyof T)[]]>;
96
97
/** Extend schema with additional properties */
98
extend<U extends ZodRawShape>(shape: U): ZodObject<T & U>;
99
100
/** Merge with another object schema */
101
merge<U extends ZodRawShape>(schema: ZodObject<U>): ZodObject<T & U>;
102
103
/** Pick specific properties */
104
pick<K extends keyof T>(keys: { [P in K]: true }): ZodObject<Pick<T, K>>;
105
106
/** Omit specific properties */
107
omit<K extends keyof T>(keys: { [P in K]: true }): ZodObject<Omit<T, K>>;
108
109
/** Make all properties optional */
110
partial(params?: { message?: string }): ZodObject<{
111
[K in keyof T]: ZodOptional<T[K]>;
112
}>;
113
114
/** Make all properties required */
115
required(params?: { message?: string }): ZodObject<{
116
[K in keyof T]: ZodNonOptional<T[K]>;
117
}>;
118
119
/** Pass through extra properties */
120
passthrough(): this;
121
122
/** Reject extra properties (strict mode) */
123
strict(): this;
124
125
/** Strip extra properties (default) */
126
strip(): this;
127
128
/** Passthrough mode (alias) */
129
loose(): this;
130
131
/** Schema for extra properties */
132
catchall(schema: ZodTypeAny): this;
133
134
/** Set specific key schema */
135
setKey(key: string, schema: ZodTypeAny): this;
136
}
137
138
type ZodRawShape = { [k: string]: ZodTypeAny };
139
```
140
141
**Examples:**
142
```typescript
143
// Basic object
144
const UserSchema = z.object({
145
name: z.string(),
146
email: z.email(),
147
age: z.number().positive(),
148
});
149
150
type User = z.infer<typeof UserSchema>;
151
// => { name: string; email: string; age: number; }
152
153
// Nested objects
154
const AddressSchema = z.object({
155
street: z.string(),
156
city: z.string(),
157
country: z.string(),
158
});
159
160
const PersonSchema = z.object({
161
name: z.string(),
162
address: AddressSchema,
163
});
164
165
// Extending objects
166
const BaseSchema = z.object({ id: z.string() });
167
const ExtendedSchema = BaseSchema.extend({
168
name: z.string(),
169
email: z.email(),
170
});
171
172
// Merging objects
173
const ProfileSchema = z.object({ bio: z.string() });
174
const FullUserSchema = UserSchema.merge(ProfileSchema);
175
176
// Picking and omitting properties
177
const PublicUserSchema = UserSchema.omit({ age: true });
178
const IdNameSchema = UserSchema.pick({ name: true });
179
180
// Partial and required
181
const OptionalUserSchema = UserSchema.partial();
182
const RequiredUserSchema = OptionalUserSchema.required();
183
184
// Handling extra properties
185
const StrictSchema = z.object({ name: z.string() }).strict(); // Rejects extras
186
const LooseSchema = z.object({ name: z.string() }).passthrough(); // Keeps extras
187
const CatchallSchema = z.object({ name: z.string() }).catchall(z.string()); // Validates extras
188
```
189
190
## Tuple
191
192
```typescript { .api }
193
/**
194
* Create a tuple validation schema for fixed-length heterogeneous arrays
195
* @param items - Array of element schemas
196
* @param params - Optional configuration with description and error map
197
* @returns ZodTuple schema instance
198
*/
199
function tuple<T extends [ZodTypeAny, ...ZodTypeAny[]]>(
200
items: T,
201
params?: { description?: string; errorMap?: ZodErrorMap }
202
): ZodTuple<T>;
203
204
interface ZodTuple<T extends [ZodTypeAny, ...ZodTypeAny[]]> extends ZodType<
205
{ [K in keyof T]: z.infer<T[K]> },
206
{ [K in keyof T]: z.input<T[K]> }
207
> {
208
/** Rest element schema for variable-length tuples */
209
rest<R extends ZodTypeAny>(schema: R): ZodTuple<[...T, ...Array<R>]>;
210
211
/** Get element schemas */
212
items: T;
213
}
214
```
215
216
**Examples:**
217
```typescript
218
// Basic tuple
219
const CoordinateSchema = z.tuple([z.number(), z.number()]);
220
CoordinateSchema.parse([10, 20]); // Valid
221
type Coordinate = z.infer<typeof CoordinateSchema>;
222
// => [number, number]
223
224
// Tuple with different types
225
const PersonTupleSchema = z.tuple([z.string(), z.number(), z.boolean()]);
226
PersonTupleSchema.parse(["Alice", 25, true]); // Valid
227
228
// Tuple with rest elements
229
const VariadicTupleSchema = z
230
.tuple([z.string(), z.number()])
231
.rest(z.boolean());
232
VariadicTupleSchema.parse(["hello", 42, true, false, true]); // Valid
233
```
234
235
## Record
236
237
```typescript { .api }
238
/**
239
* Create a record validation schema with typed keys
240
* @param keySchema - Schema for record keys
241
* @param valueSchema - Schema for record values
242
* @returns ZodRecord schema instance
243
*/
244
function record<
245
K extends ZodType<string | number | symbol>,
246
V extends ZodTypeAny
247
>(keySchema: K, valueSchema: V): ZodRecord<K, V>;
248
249
/**
250
* Create a record validation schema with string keys
251
* @param valueSchema - Schema for record values
252
* @returns ZodRecord schema instance
253
*/
254
function record<V extends ZodTypeAny>(valueSchema: V): ZodRecord<ZodString, V>;
255
256
/**
257
* Create a partial record (all values optional)
258
* @param keySchema - Schema for record keys
259
* @param valueSchema - Schema for record values
260
* @returns ZodRecord with optional values
261
*/
262
function partialRecord<
263
K extends ZodType<string | number | symbol>,
264
V extends ZodTypeAny
265
>(keySchema: K, valueSchema: V): ZodRecord<K, ZodOptional<V>>;
266
267
interface ZodRecord<
268
K extends ZodType<string | number | symbol>,
269
V extends ZodTypeAny
270
> extends ZodType<Record<z.infer<K>, z.infer<V>>, Record<z.input<K>, z.input<V>>> {
271
/** Key schema */
272
keySchema: K;
273
/** Value schema */
274
valueSchema: V;
275
}
276
```
277
278
**Examples:**
279
```typescript
280
// Record with string keys
281
const StringRecordSchema = z.record(z.string());
282
StringRecordSchema.parse({ foo: "bar", baz: "qux" }); // Valid
283
284
// Record with specific key type
285
const NumericKeysSchema = z.record(z.string().regex(/^\d+$/), z.number());
286
NumericKeysSchema.parse({ "1": 100, "2": 200 }); // Valid
287
288
// Record with enum keys
289
const StatusRecordSchema = z.record(
290
z.enum(["pending", "active", "completed"]),
291
z.number()
292
);
293
294
// Partial record
295
const PartialRecordSchema = z.partialRecord(z.string(), z.number());
296
```
297
298
## Map & Set
299
300
```typescript { .api }
301
/**
302
* Create a Map validation schema
303
* @param keySchema - Schema for map keys
304
* @param valueSchema - Schema for map values
305
* @returns ZodMap schema instance
306
*/
307
function map<K extends ZodTypeAny, V extends ZodTypeAny>(
308
keySchema: K,
309
valueSchema: V
310
): ZodMap<K, V>;
311
312
/**
313
* Create a Set validation schema
314
* @param valueSchema - Schema for set values
315
* @param params - Optional configuration with description and error map
316
* @returns ZodSet schema instance
317
*/
318
function set<T extends ZodTypeAny>(
319
valueSchema: T,
320
params?: { description?: string; errorMap?: ZodErrorMap }
321
): ZodSet<T>;
322
323
interface ZodMap<K extends ZodTypeAny, V extends ZodTypeAny> extends ZodType<
324
Map<z.infer<K>, z.infer<V>>,
325
Map<z.input<K>, z.input<V>>
326
> {
327
/** Minimum map size */
328
min(size: number, msg?: string | { message?: string }): this;
329
/** Maximum map size */
330
max(size: number, msg?: string | { message?: string }): this;
331
/** Exact map size */
332
size(size: number, msg?: string | { message?: string }): this;
333
334
/** Key schema */
335
keySchema: K;
336
/** Value schema */
337
valueSchema: V;
338
}
339
340
interface ZodSet<T extends ZodTypeAny> extends ZodType<
341
Set<z.infer<T>>,
342
Set<z.input<T>>
343
> {
344
/** Minimum set size */
345
min(size: number, msg?: string | { message?: string }): this;
346
/** Maximum set size */
347
max(size: number, msg?: string | { message?: string }): this;
348
/** Exact set size */
349
size(size: number, msg?: string | { message?: string }): this;
350
351
/** Value schema */
352
valueSchema: T;
353
}
354
```
355
356
**Examples:**
357
```typescript
358
// Basic map
359
const MapSchema = z.map(z.string(), z.number());
360
const myMap = new Map([
361
["a", 1],
362
["b", 2],
363
]);
364
MapSchema.parse(myMap); // Valid
365
366
// Map with constraints
367
const LimitedMapSchema = z.map(z.string(), z.number()).min(1).max(100);
368
369
// Complex map types
370
const UserMapSchema = z.map(
371
z.string().uuid(),
372
z.object({
373
name: z.string(),
374
email: z.email(),
375
})
376
);
377
378
// Basic set
379
const SetSchema = z.set(z.string());
380
const mySet = new Set(["a", "b", "c"]);
381
SetSchema.parse(mySet); // Valid
382
383
// Set with constraints
384
const LimitedSetSchema = z.set(z.number()).min(1).max(10);
385
386
// Set with complex types
387
const UserIdSetSchema = z.set(z.string().uuid());
388
```
389
390
## Enum & Literal
391
392
```typescript { .api }
393
/**
394
* Create an enum validation schema
395
* @param values - Array of enum values
396
* @param params - Optional configuration with description and error map
397
* @returns ZodEnum schema instance
398
*/
399
function enum<T extends [string, ...string[]]>(
400
values: T,
401
params?: { description?: string; errorMap?: ZodErrorMap }
402
): ZodEnum<T>;
403
404
/**
405
* Create a native enum validation schema (TypeScript enums)
406
* @param enumObject - TypeScript enum object
407
* @param params - Optional configuration with description and error map
408
* @returns ZodEnum schema instance
409
*/
410
function nativeEnum<T extends { [k: string]: string | number }>(
411
enumObject: T,
412
params?: { description?: string; errorMap?: ZodErrorMap }
413
): ZodEnum<[T[keyof T], ...T[keyof T][]]>;
414
415
/**
416
* Create a literal value validation schema
417
* @param value - Literal value to match
418
* @returns ZodLiteral schema instance
419
*/
420
function literal<T extends Primitive>(value: T): ZodLiteral<T>;
421
422
interface ZodEnum<T extends [string, ...string[]]> extends ZodType<T[number], T[number]> {
423
/** Record of enum entries */
424
enum: { [K in T[number]]: K };
425
/** Array of enum values */
426
options: T;
427
428
/** Extract subset of enum */
429
extract<U extends T[number][]>(keys: U): ZodEnum<U>;
430
/** Exclude subset of enum */
431
exclude<U extends T[number][]>(keys: U): ZodEnum<Exclude<T[number], U[number]>[]>;
432
}
433
434
interface ZodLiteral<T extends Primitive> extends ZodType<T, T> {
435
/** The literal value */
436
value: T;
437
}
438
439
type Primitive = string | number | bigint | boolean | null | undefined;
440
```
441
442
**Examples:**
443
```typescript
444
// Basic enum
445
const ColorSchema = z.enum(["red", "green", "blue"]);
446
ColorSchema.parse("red"); // Valid
447
ColorSchema.parse("yellow"); // Invalid
448
449
type Color = z.infer<typeof ColorSchema>;
450
// => "red" | "green" | "blue"
451
452
// Access enum values
453
ColorSchema.enum.red; // "red"
454
ColorSchema.options; // ["red", "green", "blue"]
455
456
// Extract and exclude
457
const PrimaryColorSchema = ColorSchema.extract(["red", "blue"]);
458
const NonRedSchema = ColorSchema.exclude(["red"]);
459
460
// Native TypeScript enum
461
enum Status {
462
Pending = "pending",
463
Active = "active",
464
Completed = "completed",
465
}
466
467
const StatusSchema = z.nativeEnum(Status);
468
StatusSchema.parse(Status.Active); // Valid
469
StatusSchema.parse("active"); // Valid
470
471
// String literal
472
const HelloSchema = z.literal("hello");
473
HelloSchema.parse("hello"); // Valid
474
HelloSchema.parse("world"); // Invalid
475
476
// Number literal
477
const AnswerSchema = z.literal(42);
478
AnswerSchema.parse(42); // Valid
479
480
// Boolean literal
481
const TrueSchema = z.literal(true);
482
483
// Null literal
484
const NullSchema = z.literal(null);
485
486
// Combine literals with union for multiple allowed values
487
const DirectionSchema = z.union([
488
z.literal("north"),
489
z.literal("south"),
490
z.literal("east"),
491
z.literal("west"),
492
]);
493
494
// Or use enum for the same effect
495
const DirectionEnumSchema = z.enum(["north", "south", "east", "west"]);
496
```
497
498
## Common Patterns
499
500
```typescript
501
// API response
502
const ResponseSchema = z.object({
503
data: z.array(z.object({
504
id: z.string(),
505
name: z.string(),
506
})),
507
meta: z.object({
508
page: z.number(),
509
total: z.number(),
510
}),
511
});
512
513
// Form validation
514
const FormSchema = z.object({
515
name: z.string().min(2),
516
email: z.email(),
517
tags: z.array(z.string()).optional(),
518
settings: z.record(z.string(), z.boolean()),
519
});
520
521
// Configuration
522
const ConfigSchema = z.object({
523
env: z.enum(["dev", "staging", "prod"]),
524
features: z.set(z.string()),
525
ports: z.map(z.string(), z.number()),
526
});
527
```
528