<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Zod с .refine() = валидационные правила без лишней возни]]></title><description><![CDATA[<p dir="auto">Встречайте! Если кто не знал то <code>Zod</code> — современная <code>TypeScript-first</code> библиотека для валидации данных, сочетающая простоту декларативного синтаксиса с мощными возможностями. Но что делать, когда стандартных проверок недостаточно? На помощь приходит .refine()!</p>
<h2>Просто для сложных правил</h2>
<p dir="auto">нужно проверить, что пользователь выбрал хотя бы одну опцию подписки. Стандартные валидаторы вроде <code>z.boolean()</code> не умеют работать с взаимосвязями между полями. Остается писать кастомные функции? Не обязательно.</p>
<p dir="auto">Решение: <code>.refine()</code></p>
<p dir="auto">Метод <code>.refine()</code> позволяет добавить любое кастомное правило к схеме, сохранив элегантность <code>Zod</code>. Его суть:</p>
<pre><code class="language-js">.refine(validator, { message, path })
</code></pre>
<ul>
<li><code>validator</code>: функция, возвращающая boolean (или Promise для асинхронной валидации)</li>
<li><code>message</code>: кастомное сообщение об ошибке</li>
<li><code>path</code>: куда привязать ошибку (полезно для форм!)</li>
</ul>
<p dir="auto"><strong>Реальный пример</strong>:</p>
<pre><code class="language-js">export const SubscriptionSchema = z
  .object({
    email: z.string().email(),
    newsletter: z.boolean().optional(),
    promotions: z.boolean().optional(),
    updates: z.boolean().optional(),
  })
  .refine(
    (data) =&gt; data.newsletter || data.promotions || data.updates, 
    {
      message: "Выберите хотя бы одну опцию подписки",
      path: ["subscriptionOptions"] // Ошибка привязывается не к полю, а к группе!
    }
  );
</code></pre>
<ul>
<li>Стандартные правила: <code>email</code> проверяется на корректность, булевы поля опциональны.</li>
<li>Кастомное правило: <code>.refine()</code> проверяет, что хотя бы одно из полей <code>newsletter</code>, <code>promotions</code> или <code>updates</code> равно <code>true</code>.</li>
<li>При ошибке:
<ul>
<li>Возвращается понятное сообщение</li>
<li>Ошибка привязывается к псевдо-полю <code>subscriptionOptions</code> (удобно для отображения в UI!)</li>
</ul>
</li>
</ul>
<p dir="auto"><strong>Тестируем</strong>:</p>
<pre><code class="language-js">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: Выберите хотя бы одну опцию подписки
</code></pre>
<h3>Почему это круто?</h3>
<ol>
<li>Читаемость: Правила валидации как документация.</li>
<li>Типобезопасность: <code>z.infer&lt;typeof SubscriptionSchema&gt;</code> автоматически генерирует тип:</li>
</ol>
<pre><code class="language-js">type Subscription = {
  email: string;
  newsletter?: boolean;
  promotions?: boolean;
  updates?: boolean;
}
</code></pre>
<ol start="3">
<li>Гибкость: Можно проверять любые условия между полями:
<ul>
<li>“Если выбрана рассылка, телефон обязателен”</li>
<li>“Сумма заказа &gt; 1000”</li>
</ul>
</li>
<li>Интеграция с формами: Кастомный <code>path</code> позволяет подсветить ошибку в нужном месте интерфейса.</li>
</ol>
<p dir="auto">С <code>.refine()</code> вы получаете мощь кастомной валидации без boilerplate-кода. Больше никаких велосипедов с ручными проверками после парсинга! Zod позволяет описывать сложные правила в 2-3 строки, сохраняя TypeScript-типы и человекочитаемый синтаксис.</p>
<blockquote>
<p dir="auto"><img src="https://forum.exlends.ru/assets/plugins/nodebb-plugin-emoji/emoji/android/2728.png?v=a1e94250dac" class="not-responsive emoji emoji-android emoji--sparkles" style="height:23px;width:auto;vertical-align:middle" title="✨" alt="✨" /> Код валидации должен быть таким же чистым, как и код приложения.<br />
С Zod и .refine() — это реальность.</p>
</blockquote>
]]></description><link>https://forum.exlends.ru/topic/189/zod-s-.refine-validacionnye-pravila-bez-lishnej-vozni</link><generator>RSS for Node</generator><lastBuildDate>Wed, 24 Jun 2026 06:16:08 GMT</lastBuildDate><atom:link href="https://forum.exlends.ru/topic/189.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 16 Jul 2025 19:50:59 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Zod с .refine() = валидационные правила без лишней возни on Thu, 17 Jul 2025 19:31:51 GMT]]></title><description><![CDATA[<p dir="auto"><a href="/topic/18/zod-nestjs-vmesto-slass-validator">статья про zod и nest js</a> здесь тоже есть примеры использования, и как заменить<br />
устаревший classvalidator</p>
]]></description><link>https://forum.exlends.ru/post/356</link><guid isPermaLink="true">https://forum.exlends.ru/post/356</guid><dc:creator><![CDATA[Aladdin]]></dc:creator><pubDate>Thu, 17 Jul 2025 19:31:51 GMT</pubDate></item></channel></rss>