0
# Parsing and Validation
1
2
Validation methods with synchronous/asynchronous and throwing/safe variants.
3
4
## Parse Methods
5
6
```typescript { .api }
7
interface ZodType<Output, Input> {
8
/**
9
* Parse and validate data (throws on error)
10
* @param data - Data to validate
11
* @param params - Optional parse context with custom error map
12
* @returns Validated output
13
* @throws ZodError if validation fails
14
*/
15
parse(data: unknown, params?: ParseContext): Output;
16
17
/**
18
* Safe parse (returns result object instead of throwing)
19
* @param data - Data to validate
20
* @param params - Optional parse context
21
* @returns Success or error result
22
*/
23
safeParse(data: unknown, params?: ParseContext): SafeParseResult<Output>;
24
25
/**
26
* Async parse (throws on error)
27
* @param data - Data to validate
28
* @param params - Optional parse context
29
* @returns Promise resolving to validated output
30
* @throws ZodError if validation fails
31
*/
32
parseAsync(data: unknown, params?: ParseContext): Promise<Output>;
33
34
/**
35
* Async safe parse (returns result object)
36
* @param data - Data to validate
37
* @param params - Optional parse context
38
* @returns Promise resolving to success or error result
39
*/
40
safeParseAsync(data: unknown, params?: ParseContext): Promise<SafeParseResult<Output>>;
41
42
/**
43
* Alias for safeParseAsync
44
* @param data - Data to validate
45
* @param params - Optional parse context
46
* @returns Promise resolving to success or error result
47
*/
48
spa(data: unknown, params?: ParseContext): Promise<SafeParseResult<Output>>;
49
}
50
51
interface ParseContext {
52
/** Custom error map for error messages */
53
error?: ZodErrorMap;
54
/** Include input field in issue objects */
55
reportInput?: boolean;
56
/** Skip eval-based fast path optimization */
57
jitless?: boolean;
58
}
59
60
type SafeParseResult<T> = SafeParseSuccess<T> | SafeParseError;
61
62
interface SafeParseSuccess<T> {
63
success: true;
64
data: T;
65
}
66
67
interface SafeParseError {
68
success: false;
69
error: ZodError;
70
}
71
```
72
73
## Parse (Throwing)
74
75
Validates and returns data, throws `ZodError` on failure.
76
77
```typescript
78
const UserSchema = z.object({
79
name: z.string(),
80
age: z.number(),
81
});
82
83
// Success
84
const user = UserSchema.parse({ name: "Alice", age: 25 });
85
86
// Failure (throws)
87
try {
88
UserSchema.parse({ name: "Bob", age: "invalid" });
89
} catch (error) {
90
if (error instanceof z.ZodError) {
91
console.log(error.issues);
92
}
93
}
94
95
// With custom error map
96
UserSchema.parse(data, {
97
errorMap: (issue, ctx) => ({
98
message: `Custom error: ${issue.code}`,
99
}),
100
});
101
```
102
103
## Safe Parse (Non-Throwing)
104
105
Returns result object instead of throwing.
106
107
```typescript
108
const result = UserSchema.safeParse(data);
109
110
if (result.success) {
111
console.log(result.data); // Validated data
112
} else {
113
console.log(result.error); // ZodError
114
}
115
116
// Type narrowing
117
if (result.success) {
118
const user: User = result.data; // TypeScript knows this is valid
119
} else {
120
const error: z.ZodError = result.error;
121
}
122
123
// API handler pattern
124
function handleRequest(body: unknown) {
125
const result = UserSchema.safeParse(body);
126
127
if (!result.success) {
128
return { status: 400, error: result.error.format() };
129
}
130
131
return { status: 200, data: result.data };
132
}
133
```
134
135
## Async Parsing
136
137
For schemas with async refinements or transformations.
138
139
```typescript
140
// Async refinement
141
const UserSchema = z.object({
142
username: z.string(),
143
}).refine(
144
async (data) => {
145
const available = await checkAvailability(data.username);
146
return available;
147
},
148
{ message: "Username taken" }
149
);
150
151
// Throwing async
152
try {
153
const user = await UserSchema.parseAsync(data);
154
} catch (error) {
155
if (error instanceof z.ZodError) {
156
console.log(error.issues);
157
}
158
}
159
160
// Safe async
161
const result = await UserSchema.safeParseAsync(data);
162
// Or use alias:
163
const result = await UserSchema.spa(data);
164
165
if (result.success) {
166
console.log(result.data);
167
} else {
168
console.log(result.error);
169
}
170
171
// Async transformation
172
const AsyncSchema = z.string().transform(async (val) => {
173
const response = await fetch(`/api/${val}`);
174
return response.json();
175
});
176
177
const data = await AsyncSchema.parseAsync("123");
178
```
179
180
## Codec Methods
181
182
For bidirectional encoding/decoding with codec schemas.
183
184
```typescript { .api }
185
interface ZodType<Output, Input> {
186
// Decode: Input -> Output
187
/**
188
* Decode input to output (throws on error)
189
* @param data - Input data to decode
190
* @param params - Optional parse context
191
* @returns Decoded output
192
* @throws ZodError if decoding fails
193
*/
194
decode(data: unknown, params?: ParseContext): Output;
195
196
/**
197
* Safe decode (returns result object)
198
* @param data - Input data to decode
199
* @param params - Optional parse context
200
* @returns Success or error result
201
*/
202
safeDecode(data: unknown, params?: ParseContext): SafeParseResult<Output>;
203
204
/**
205
* Async decode (throws on error)
206
* @param data - Input data to decode
207
* @param params - Optional parse context
208
* @returns Promise resolving to decoded output
209
* @throws ZodError if decoding fails
210
*/
211
decodeAsync(data: unknown, params?: ParseContext): Promise<Output>;
212
213
/**
214
* Async safe decode (returns result object)
215
* @param data - Input data to decode
216
* @param params - Optional parse context
217
* @returns Promise resolving to success or error result
218
*/
219
safeDecodeAsync(data: unknown, params?: ParseContext): Promise<SafeParseResult<Output>>;
220
221
// Encode: Output -> Input
222
/**
223
* Encode output to input (throws on error)
224
* @param data - Output data to encode
225
* @param params - Optional parse context
226
* @returns Encoded input
227
* @throws ZodError if encoding fails
228
*/
229
encode(data: Output, params?: ParseContext): Input;
230
231
/**
232
* Safe encode (returns result object)
233
* @param data - Output data to encode
234
* @param params - Optional parse context
235
* @returns Success or error result
236
*/
237
safeEncode(data: Output, params?: ParseContext): SafeParseResult<Input>;
238
239
/**
240
* Async encode (throws on error)
241
* @param data - Output data to encode
242
* @param params - Optional parse context
243
* @returns Promise resolving to encoded input
244
* @throws ZodError if encoding fails
245
*/
246
encodeAsync(data: Output, params?: ParseContext): Promise<Input>;
247
248
/**
249
* Async safe encode (returns result object)
250
* @param data - Output data to encode
251
* @param params - Optional parse context
252
* @returns Promise resolving to success or error result
253
*/
254
safeEncodeAsync(data: Output, params?: ParseContext): Promise<SafeParseResult<Input>>;
255
}
256
```
257
258
**Examples:**
259
```typescript
260
// Date codec
261
const DateCodec = z.codec(
262
z.string().transform((s) => new Date(s)),
263
z.date().transform((d) => d.toISOString())
264
);
265
266
const decoded = DateCodec.decode("2024-01-01"); // Date object
267
const encoded = DateCodec.encode(new Date()); // ISO string
268
269
// Safe decode/encode
270
const result = DateCodec.safeDecode("2024-01-01");
271
if (result.success) {
272
console.log(result.data); // Date object
273
}
274
```
275
276
## Method Comparison
277
278
```typescript
279
const schema = z.string().email();
280
281
// Synchronous
282
schema.parse(data); // Throws on error
283
schema.safeParse(data); // Returns result object
284
285
// Asynchronous
286
await schema.parseAsync(data); // Throws on error
287
await schema.safeParseAsync(data); // Returns result object
288
await schema.spa(data); // Alias for safeParseAsync
289
290
// Codec
291
schema.decode(data); // Input -> Output
292
schema.encode(data); // Output -> Input
293
```
294
295
## Common Patterns
296
297
```typescript
298
// Express middleware
299
function validateBody(schema: z.ZodSchema) {
300
return (req, res, next) => {
301
const result = schema.safeParse(req.body);
302
if (!result.success) {
303
return res.status(400).json({
304
errors: result.error.flatten().fieldErrors,
305
});
306
}
307
req.validatedBody = result.data;
308
next();
309
};
310
}
311
312
// Form validation
313
function validateForm(formData: FormData) {
314
const result = FormSchema.safeParse(
315
Object.fromEntries(formData.entries())
316
);
317
318
if (!result.success) {
319
return { success: false, errors: result.error.flatten() };
320
}
321
322
return { success: true, data: result.data };
323
}
324
325
// Async API validation
326
async function validateAsync(input: unknown) {
327
const result = await schema.safeParseAsync(input);
328
329
if (!result.success) {
330
return {
331
status: 400,
332
errors: result.error.format(),
333
};
334
}
335
336
return {
337
status: 200,
338
data: result.data,
339
};
340
}
341
```
342