Install Zod:
npm install zod
Basic schema definition and validation:
import { z } from 'zod';
const schema = z.object({
name: z.string(),
age: z.number().positive().int(),
email: z.string().email(),
});
type User = z.infer<typeof schema>; // Infer TypeScript type from schema
const result = schema.safeParse({
name: 'John Doe',
age: 30,
email: 'john@example.com',
});
if (result.success) {
console.log('Valid data:', result.data);
} else {
console.log('Validation errors:', result.error.errors);
}
Various string validation methods:
const stringSchema = z.object({
username: z.string()
.min(3, 'Username must be at least 3 characters')
.max(20, 'Username must not exceed 20 characters')
.regex(/^[a-zA-Z0-9]+$/, 'Username can only contain alphanumeric characters'),
email: z.string().email('Invalid email address'),
password: z.string()
.min(8, 'Password must be at least 8 characters')
.regex(/[A-Z]/, 'Password must contain at least one uppercase letter')
.regex(/[0-9]/, 'Password must contain at least one number'),
url: z.string().url('Invalid URL'),
});
Number validation methods:
const numberSchema = z.object({
age: z.number()
.positive('Age must be a positive number')
.int('Age must be an integer')
.min(18, 'Must be at least 18 years old')
.max(100, 'Must be at most 100 years old'),
price: z.number()
.positive('Price must be positive')
.multipleOf(0.01, 'Price must have at most 2 decimal places')
.max(1000000, 'Price must be less than 1,000,000'),
});
Boolean validation:
const booleanSchema = z.object({
agreeToTerms: z.boolean()
.refine((val) => val === true, 'You must agree to the terms'),
receiveNewsletter: z.boolean().optional(),
});
Date validation methods:
const dateSchema = z.object({
birthDate: z.date()
.max(new Date(), 'Birth date cannot be in the future'),
appointmentDate: z.date()
.min(new Date(), 'Appointment date must be in the future'),
});
Array validation methods:
const arraySchema = z.object({
tags: z.array(z.string())
.nonempty('At least one tag is required')
.max(5, 'Maximum 5 tags allowed'),
scores: z.array(z.number().positive().int())
.min(3, 'At least 3 scores are required'),
});
Nested object validation:
const addressSchema = z.object({
street: z.string(),
city: z.string(),
zipCode: z.string().regex(/^d{5}$/, 'Invalid zip code'),
});
const userSchema = z.object({
name: z.string(),
email: z.string().email(),
address: addressSchema,
});
Using union and intersection types:
const unionSchema = z.union([
z.string(),
z.number(),
z.boolean(),
]);
const intersectionSchema = z.intersection(
z.object({ name: z.string() }),
z.object({ age: z.number() })
);
Creating enum schemas:
const RoleEnum = z.enum(['admin', 'user', 'guest']);
const userSchema = z.object({
name: z.string(),
role: RoleEnum,
});
Handling optional and nullable fields:
const schema = z.object({
name: z.string(),
middleName: z.string().optional(),
nickname: z.string().nullable(),
age: z.number().optional().nullable(),
});
optional(): The field may or may not be present (its value can be undefined if not provided).
nullable(): The field must be present but can be explicitly set to null.
Creating custom validation rules:
const customSchema = z.object({
password: z.string()
.min(8)
.refine((val) => /[A-Z]/.test(val), 'Password must contain an uppercase letter')
.refine((val) => /[0-9]/.test(val), 'Password must contain a number'),
confirmPassword: z.string(),
}).refine((data) => data.password === data.confirmPassword, {
message: "Passwords don't match",
path: ["confirmPassword"],
});
Handling validation errors:
const schema = z.object({
name: z.string(),
email: z.string().email(),
});
const result = schema.safeParse({ name: '', email: 'invalid' });
if (!result.success) {
console.log('Validation errors:');
result.error.issues.forEach((issue) => {
console.log(`${issue.path.join('.')}: ${issue.message}`);
});
}
Using parse and safeparse methods:
const schema = z.object({
name: z.string(),
age: z.number(),
});
// Parsing (throws error if invalid)
try {
const data = schema.parse({ name: 'John', age: '30' });
console.log('Parsed data:', data);
} catch (error) {
if (error instanceof z.ZodError) {
console.log('Validation errors:', error.errors);
}
}
// Safeparsing (returns success/error object)
const result = schema.safeParse({ name: 'John', age: '30' });
if (result.success) {
console.log('Valid data:', result.data);
} else {
console.log('Validation errors:', result.error.errors);
}
Using Zod with React and a form library like React Hook Form:
import React from 'react';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
const schema = z.object({
name: z.string().min(1, 'Name is required'),
email: z.string().email('Invalid email'),
});
type FormData = z.infer<typeof schema>;
function Form() {
const { register, handleSubmit, formState: { errors } } = useForm<FormData>({
resolver: zodResolver(schema),
});
const onSubmit = (data: FormData) => console.log(data);
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register("name")} />
{errors.name && <p>{errors.name.message}</p>}
<input {...register("email")} />
{errors.email && <p>{errors.email.message}</p>}
<button type="submit">Submit</button>
</form>
);
}
2024 © All rights reserved - buraxta.com