Валидация email-адресов в Zod реализуется через встроенный метод
z.string().email(), который опирается на проверку
соответствия строкового значения стандартному формату электронной почты.
Несмотря на кажущуюся простоту, обработка email требует учета множества
нюансов: допустимые символы, наличие доменной части, локальной части,
ограничения длины и специфические исключения, предусмотренные RFC.
Базовая схема:
import { z } from "zod";
const EmailSchema = z.string().email();
Такой вариант применяет стандартную проверку, основанную на
регулярном выражении и внутренних правилах библиотеки. Входное значение
должно быть строкой, содержащей символ @, разделяющий
локальную и доменную части.
Zod позволяет дополнительно задавать ограничения:
const EmailSchema = z
.string()
.email()
.min(5)
.max(254);
Ограничение длины важно, поскольку реальные email-адреса редко превышают 254 символа (ограничение стандарта SMTP).
Часто требуется предварительная очистка входных данных:
const EmailSchema = z
.string()
.trim()
.toLowerCase()
.email();
Приведение к нижнему регистру полезно для доменной части, так как она
регистронезависима. Однако локальная часть (до @)
теоретически может быть чувствительной к регистру, что иногда требует
осторожности при трансформациях.
const EmailSchema = z
.string()
.email({ message: "Некорректный email-адрес" });
Встроенные сообщения об ошибках могут быть переопределены для интеграции в пользовательские интерфейсы.
Стандартная проверка Zod не покрывает все возможные RFC-спецификации, например:
+,
!, %)Для более строгой проверки применяется refine:
const EmailSchema = z.string().refine((val) => {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(val);
});
Однако такие регулярные выражения часто упрощают реальную модель email и могут давать ложные срабатывания.
Проверка URL осуществляется через z.string().url(),
который валидирует строку как корректный веб-адрес.
const UrlSchema = z.string().url();
Поддерживаются стандартные протоколы, такие как http,
https, а также в зависимости от окружения — дополнительные
схемы.
URL разбивается на следующие компоненты:
Пример допустимого значения:
const result = UrlSchema.parse("https://example.com/path?query=1#section");
В некоторых случаях требуется разрешить только безопасные схемы:
const UrlSchema = z.string().url().refine((val) => {
return val.startsWith("https://");
});
Более строгий вариант:
const UrlSchema = z.string().refine((val) => {
try {
const url = new URL(val);
return url.protocol === "https:";
} catch {
return false;
}
});
Zod опирается на стандартные механизмы разбора URL, что означает:
:3000)Международные домены (например, с кириллицей) требуют предварительной обработки:
const UrlSchema = z.string().url().transform((val) => {
const url = new URL(val);
return url.toString();
});
Однако преобразование IDN в punycode часто выполняется вне Zod, на уровне вспомогательных библиотек.
UUID (Universally Unique Identifier) используется для идентификаторов
объектов, особенно в распределённых системах. В Zod предусмотрена
встроенная проверка через z.string().uuid().
const IdSchema = z.string().uuid();
Zod позволяет ограничивать версию UUID:
const IdSchema = z.string().uuid({ version: "uuidv4" });
Наиболее распространённый вариант — UUID v4, основанный на случайных числах.
Пример:
"550e8400-e29b-41d4-a716-446655440000"
UUID состоит из 32 шестнадцатеричных символов, разбитых на группы:
xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
где:
Zod проверяет:
UUID иногда приводится к единому виду:
const IdSchema = z
.string()
.uuid()
.transform((val) => val.toLowerCase());
Это упрощает сравнение значений в базе данных, где регистр не имеет значения.
UUID часто комбинируется с другими схемами:
const EntitySchema = z.object({
id: z.string().uuid(),
createdAt: z.string().datetime(),
});
UUID не гарантирует:
Поэтому валидация в Zod проверяет только синтаксическую корректность, а не семантические свойства.
В реальных приложениях эти типы часто объединяются в единые структуры данных:
const UserSchema = z.object({
id: z.string().uuid(),
email: z.string().email(),
website: z.string().url().optional(),
});
Такие схемы позволяют формализовать контракт данных на уровне приложения, минимизируя необходимость ручной проверки.
Иногда требуется зависимая логика:
const Schema = z.object({
email: z.string().email(),
backupEmail: z.string().email().optional(),
}).refine((data) => {
return data.email !== data.backupEmail;
});
refine вместо встроенных методов без
необходимостиuuid() сложными регулярными
выражениямиnew URL()Zod позволяет связывать валидацию с типами TypeScript:
type User = z.infer<typeof UserSchema>;
Это обеспечивает синхронизацию структуры данных между runtime-валидацией и компиляцией, снижая вероятность расхождений между ожидаемыми и фактическими форматами Email, URL и UUID в системе.