Platform
    • Naming & Linter Rules
    • Styling Standards
    • Theme
    • Zod & Typing
    • Internationalization
Projects
  • API Connections & Tools
  1. Documentation
  2. Zod & Typing

Validation & Type Safety with Zod

Deterministic validation layer ensuring that all data entering the system conforms to the defined architectural contracts.

Zod Validation Architecture

Benefits: Zod allows combining runtime validation with TypeScript typing, creating a single source of truth for forms and API data.

Zod Schema & Types Structure

Naming Conventions

  • Zod Schemas:

    Located in the schema folder. Files are named following the [name].schema.ts pattern. Schemas are named in uppercase (e.g., ENTITY_SCHEMA).

  • Types & Interfaces:

    Located in the types folder. Types inferred from schemas are named with a T prefix (e.g., TEntitySchema). All form field enums are stored in ENUM_FORM_... objects.

01Schema Definition

Creating a Zod object using i18nKey for localized error messages.

entities/entity-name/schema/entity-name.schema.ts
1import { z } from "zod"; 2import { type TEntityPageKeys, i18nKey } from "@/shared/config"; 3import { ENUM_FORM_ENTITY } from "../types"; 4 5const msg = i18nKey<TEntityPageKeys>(); 6 7export const ENTITY_SCHEMA = z.object({ 8 [ENUM_FORM_ENTITY.DESCRIPTION]: z 9 .string() 10 .trim() 11 .min(1, { 12 message: msg("form.overview.fields.description.errors.required") 13 }) 14 .min(3, { 15 message: msg("form.overview.fields.description.errors.min") 16 }) 17 .max(5000, { 18 message: msg("form.overview.fields.description.errors.max") 19 }), 20});

02Type Inference

Using z.infer to automatically generate TypeScript types from the schema.

entities/entity-name/types/entity-name.types.ts
1import { z } from "zod"; 2import type { ENTITY_SCHEMA } from "../schema"; 3 4export const ENUM_FORM_ENTITY = { 5 DESCRIPTION: "description", 6} as const; 7 8export type TEntitySchema = z.infer<typeof ENTITY_SCHEMA>;

03Form Integration

Connecting the schema to react-hook-form via zodResolver.

widgets/entity-name/ui/entity-name.tsx
1import { useForm } from "react-hook-form"; 2import { zodResolver } from "@hookform/resolvers/zod"; 3import { type TEntitySchema, ENTITY_SCHEMA } from "@/entities/entity-name"; 4 5const form = useForm<TEntitySchema>({ 6 resolver: zodResolver(ENTITY_SCHEMA), 7 mode: "onSubmit" 8});