Deterministic validation layer ensuring that all data entering the system conforms to the defined architectural contracts.
Benefits: Zod allows combining runtime validation with TypeScript typing, creating a single source of truth for forms and API data.
Located in schema/. Strictly one pair per operation: [name]-create.schema.ts ↔ [name]-create-form.types.ts. Runtime only — no z.infer exports here; ENUM_FORM_* is imported by the direct file path, not the ../types barrel.
Located in types/[name]-[op]-form.types.ts. z.infer form types (e.g. TEntityCreateSchema) and ENUM_FORM_... live here, never in schema files. The schema is imported only via import type.
Creating a Zod object using i18nKey for localized error messages.
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});Using z.infer to automatically generate TypeScript types from the schema.
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;Connecting the schema to react-hook-form via 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});