Appearance
Zod
Zod is a TypeScript-first schema validation library with static type inference. It allows you to build schemas that validate data at runtime while automatically providing TypeScript types at compile time.
Purpose
Zod serves as a bridge between runtime validation and compile-time type safety. It's particularly useful for:
- API Response Validation: Ensuring external data matches expected types
- Form Data Validation: Validating user input with detailed error messages
- Configuration Parsing: Safely parsing environment variables and config files
- Data Transformation: Converting and coercing data types during validation
Key Features
Runtime Validation
Zod validates data at runtime and provides detailed error messages when validation fails:
typescript
import { z } from "zod";
const UserSchema = z.object({
id: z.number(),
name: z.string().min(1),
email: z.string().email(),
age: z.number().min(18).optional(),
});
// Valid data
const validUser = UserSchema.parse({
id: 1,
name: "John Doe",
email: "john@example.com",
});
// Invalid data - throws ZodError with detailed messages
try {
UserSchema.parse({
id: "not a number",
name: "",
email: "invalid-email",
});
} catch (error) {
console.log(error.issues); // Detailed validation errors
}
Type Inference
Zod automatically infers TypeScript types from your schemas, eliminating the need to define types separately:
typescript
import { z } from "zod";
const ProductSchema = z.object({
id: z.string(),
name: z.string(),
price: z.number().positive(),
categories: z.array(z.string()),
metadata: z.record(z.string(), z.unknown()).optional(),
});
// TypeScript type is automatically inferred
type Product = z.infer<typeof ProductSchema>;
// Equivalent to:
// type Product = {
// id: string
// name: string
// price: number
// categories: string[]
// metadata?: Record<string, unknown>
// }
function processProduct(product: Product) {
// Full type safety without manual type definitions
console.log(`Processing ${product.name} with price $${product.price}`);
}
Safe Parsing
Use safeParse
to handle validation without throwing errors:
typescript
const result = UserSchema.safeParse(unknownData);
if (result.success) {
// result.data is fully typed
console.log(`Welcome ${result.data.name}!`);
} else {
// result.error contains validation issues
console.log("Validation failed:", result.error.issues);
}