Zod с .refine() = валидационные правила без лишней возни
-
Встречайте! Если кто не знал то
Zod
— современнаяTypeScript-first
библиотека для валидации данных, сочетающая простоту декларативного синтаксиса с мощными возможностями. Но что делать, когда стандартных проверок недостаточно? На помощь приходит .refine()!Просто для сложных правил
нужно проверить, что пользователь выбрал хотя бы одну опцию подписки. Стандартные валидаторы вроде
z.boolean()
не умеют работать с взаимосвязями между полями. Остается писать кастомные функции? Не обязательно.Решение:
.refine()
Метод
.refine()
позволяет добавить любое кастомное правило к схеме, сохранив элегантностьZod
. Его суть:.refine(validator, { message, path })
validator
: функция, возвращающая boolean (или Promise для асинхронной валидации)message
: кастомное сообщение об ошибкеpath
: куда привязать ошибку (полезно для форм!)
Реальный пример:
export const SubscriptionSchema = z .object({ email: z.string().email(), newsletter: z.boolean().optional(), promotions: z.boolean().optional(), updates: z.boolean().optional(), }) .refine( (data) => data.newsletter || data.promotions || data.updates, { message: "Выберите хотя бы одну опцию подписки", path: ["subscriptionOptions"] // Ошибка привязывается не к полю, а к группе! } );
- Стандартные правила:
email
проверяется на корректность, булевы поля опциональны. - Кастомное правило:
.refine()
проверяет, что хотя бы одно из полейnewsletter
,promotions
илиupdates
равноtrue
. - При ошибке:
- Возвращается понятное сообщение
- Ошибка привязывается к псевдо-полю
subscriptionOptions
(удобно для отображения в UI!)
Тестируем:
const result = SubscriptionSchema.safeParse({ email: "user@example.com", newsletter: false, promotions: false, updates: false, }); console.log(result.success ? "✔ Valid" : "✕ Error:", result.error?.issues[0]?.message); // ✕ Error: Выберите хотя бы одну опцию подписки
Почему это круто?
- Читаемость: Правила валидации как документация.
- Типобезопасность:
z.infer<typeof SubscriptionSchema>
автоматически генерирует тип:
type Subscription = { email: string; newsletter?: boolean; promotions?: boolean; updates?: boolean; }
- Гибкость: Можно проверять любые условия между полями:
- “Если выбрана рассылка, телефон обязателен”
- “Сумма заказа > 1000”
- Интеграция с формами: Кастомный
path
позволяет подсветить ошибку в нужном месте интерфейса.
С
.refine()
вы получаете мощь кастомной валидации без boilerplate-кода. Больше никаких велосипедов с ручными проверками после парсинга! Zod позволяет описывать сложные правила в 2-3 строки, сохраняя TypeScript-типы и человекочитаемый синтаксис.Код валидации должен быть таким же чистым, как и код приложения.
С Zod и .refine() — это реальность. -
статья про zod и nest js здесь тоже есть примеры использования, и как заменить
устаревший classvalidator
© 2024 - 2025 RosDesk, Inc. Все права защищены.