Объектная схема в Zod строится вокруг функции
z.object(), которая позволяет описывать форму
JavaScript-объекта через набор строго типизированных полей. Каждый ключ
объекта ассоциируется с отдельной схемой, что обеспечивает детальную
проверку структуры входных данных на уровне рантайма.
import { z } from "zod";
const UserSchema = z.object({
id: z.number(),
name: z.string(),
email: z.string().email(),
});
Каждое поле объекта валидируется независимо. При несоответствии хотя бы одного поля вся валидация считается неуспешной.
z.object() принимает объект, где ключи соответствуют
полям, а значения — схемам.
const ProductSchema = z.object({
title: z.string(),
price: z.number(),
inStock: z.boolean(),
});
Важный аспект: структура объекта фиксируется строго по ключам. Лишние
поля по умолчанию удаляются (поведение зависит от режима:
strip, strict, passthrough).
Лишние поля удаляются:
const schema = z.object({
name: z.string(),
});
schema.parse({
name: "Book",
extra: 123,
});
Результат: { name: "Book" }
Запрещает любые лишние поля:
const schema = z.object({
name: z.string(),
}).strict();
Вход с дополнительными ключами приведёт к ошибке валидации.
Сохраняет все дополнительные поля:
const schema = z.object({
name: z.string(),
}).passthrough();
Результат сохраняет как определённые, так и неизвестные поля.
Метод partial() делает все поля необязательными:
const schema = z.object({
name: z.string(),
age: z.number(),
}).partial();
Теперь допустим объект:
{ name: "Alex" }
Каждое поле оборачивается в optional().
const UserBase = z.object({
id: z.number(),
name: z.string(),
email: z.string(),
});
const NameOnly = UserBase.pick({
name: true,
});
const PublicUser = UserBase.omit({
email: true,
});
Метод extend() добавляет новые поля к существующей
схеме:
const BaseUser = z.object({
id: z.number(),
name: z.string(),
});
const ExtendedUser = BaseUser.extend({
email: z.string().email(),
});
Это основной механизм композиции объектных схем.
merge() объединяет две объектные схемы:
const A = z.object({
a: z.string(),
});
const B = z.object({
b: z.number(),
});
const C = A.merge(B);
Результирующая схема содержит поля обеих структур.
Для вложенных объектов применяется рекурсивное преобразование:
const schema = z.object({
user: z.object({
name: z.string(),
profile: z.object({
age: z.number(),
}),
}),
}).deepPartial();
Все уровни вложенности становятся необязательными.
Zod поддерживает неограниченную вложенность:
const schema = z.object({
user: z.object({
id: z.number(),
settings: z.object({
theme: z.string(),
}),
}),
});
Каждый уровень проходит независимую валидацию.
catchall() определяет поведение для неизвестных
свойств:
const schema = z.object({
name: z.string(),
}).catchall(z.string());
Теперь любые дополнительные ключи должны соответствовать заданной схеме.
Для динамических ключей используется z.record():
const schema = z.object({
translations: z.record(z.string()),
});
Это полезно для словарей, где ключи неизвестны заранее.
Жёсткая проверка, выбрасывает исключение при ошибке:
schema.parse(data);
Возвращает результат без исключений:
const result = schema.safeParse(data);
if (!result.success) {
console.log(result.error);
}
Метод refine() добавляет пользовательскую проверку:
const schema = z.object({
password: z.string(),
confirmPassword: z.string(),
}).refine(data => data.password === data.confirmPassword, {
message: "Пароли не совпадают",
});
Используется для межполейной логики.
Для самоссылочных структур применяется z.lazy():
const Category = z.lazy(() =>
z.object({
name: z.string(),
children: z.array(Category),
})
);
Это позволяет описывать древовидные структуры без циклических ошибок.
z.strictObject() используется для жёсткого контроля
структуры:
const schema = z.strictObject({
id: z.number(),
});
Любые дополнительные поля считаются ошибкой, независимо от глобального режима.
extend, merge,
pick, omitrecordlazyrefineОшибки формируются на уровне каждого поля и агрегируются в структуру
ZodError. Внутри содержится путь (path) до
конкретного поля, что позволяет точно локализовать проблему:
{
path: ["user", "email"],
message: "Invalid email"
}
Такая структура критична при работе с глубоко вложенными объектами и формами данных.