Детерминированный слой валидации, гарантирующий, что все данные, поступающие в систему, соответствуют определенным архитектурным контрактам.
Преимущества: Zod позволяет объединить рантайм-валидацию с типизацией TypeScript, создавая единый источник истины для форм и данных API.
В schema/. Строго пара на операцию: [name]-create.schema.ts ↔ [name]-create-form.types.ts. Только runtime — без экспорта z.infer; ENUM_FORM_* импортируется по прямому пути к файлу, не через barrel ../types.
В types/[name]-[op]-form.types.ts. Типы форм через z.infer (напр. TEntityCreateSchema) и ENUM_FORM_... живут здесь, не в schema. Схема импортируется только через import type.
Создание Zod-объекта с использованием i18nKey для локализации сообщений об ошибках.
1import { z } from "zod";
2import { type TEntityPageKeys, i18nKey } from "@/shared/config";
3// прямой путь к form.types — не barrel "../types" (нет цикла schema ↔ types)
4import { ENUM_FORM_ENTITY_CREATE } from "../types/entity-name-create-form.types";
5
6const msg = i18nKey<TEntityPageKeys>();
7const F = ENUM_FORM_ENTITY_CREATE;
8
9/** Runtime only — never export inferred types from schema files.
10 * Одна схема на операцию: update — в entity-name-update.schema.ts */
11export const ENTITY_CREATE_SCHEMA = z.object({
12 [F.DESCRIPTION]: z
13 .string()
14 .trim()
15 .min(1, {
16 message: msg("form.overview.fields.description.errors.required")
17 })
18 .min(3, {
19 message: msg("form.overview.fields.description.errors.min")
20 })
21 .max(5000, {
22 message: msg("form.overview.fields.description.errors.max")
23 }),
24});Использование z.infer для автоматической генерации TypeScript типов из схемы.
1import type { FieldValues } from "react-hook-form";
2import { z } from "zod";
3// только import type — в рантайме зависимость schema → form.types односторонняя
4import type { ENTITY_CREATE_SCHEMA } from "../schema";
5
6export const ENUM_FORM_ENTITY_CREATE = {
7 DESCRIPTION: "description",
8} as const;
9
10export type ENUM_FORM_ENTITY_CREATE_TYPE =
11 (typeof ENUM_FORM_ENTITY_CREATE)[keyof typeof ENUM_FORM_ENTITY_CREATE];
12
13/** z.infer and form enums live in types/ — пара к entity-name-create.schema.ts */
14export type TEntityCreateSchema = z.infer<typeof ENTITY_CREATE_SCHEMA> &
15 FieldValues;Подключение схемы к react-hook-form через zodResolver.
1import { useForm } from "react-hook-form";
2import { zodResolver } from "@hookform/resolvers/zod";
3import {
4 type TEntityCreateSchema,
5 ENTITY_CREATE_SCHEMA,
6} from "@/entities/entity-name";
7
8const form = useForm<TEntityCreateSchema>({
9 resolver: zodResolver(ENTITY_CREATE_SCHEMA),
10 mode: "onSubmit"
11});