Инструменты кодогенерации

Инструменты кодогенерации в экосистеме Zod занимают промежуточное положение между типобезопасностью TypeScript и декларативным описанием данных. Их задача — автоматически синхронизировать структуры данных между различными слоями приложения: API, клиентом, базой данных и схемами валидации.

Одним из базовых свойств Zod является возможность вывода TypeScript-типов напрямую из схем. Это не классическая кодогенерация в файловом смысле, но именно она формирует основу всей экосистемы:

import { z } from "zod";

const UserSchema = z.object({
  id: z.string(),
  name: z.string(),
  age: z.number().optional(),
});

type User = z.infer<typeof UserSchema>;

Ключевой момент здесь заключается в том, что схема становится единым источником правды. Тип User не поддерживается вручную — он полностью выводится из Zod-описания. Это снижает дублирование и исключает расхождения между runtime-валидацией и compile-time типами.

При масштабировании проекта такие схемы начинают использоваться как входная точка для дальнейшей генерации:

  • API-контрактов
  • DTO-моделей
  • OpenAPI спецификаций
  • клиентских SDK

Генерация Zod-схем из внешних спецификаций

Один из наиболее распространённых сценариев кодогенерации — преобразование внешних контрактов в Zod-схемы.

JSON Schema → Zod

Существуют инструменты, преобразующие JSON Schema в Zod:

  • json-schema-to-zod
  • json-schema-to-zod-подобные генераторы
  • кастомные конвертеры в CLI-пайплайнах

Принцип работы заключается в маппинге стандартных JSON Schema конструкций:

JSON Schema Zod
type: "string" z.string()
type: "number" z.number()
required обязательные поля объекта
enum z.enum([...])

Пример результата генерации:

const Schema = z.object({
  status: z.enum(["active", "disabled"]),
  count: z.number(),
});

Такая генерация часто используется при интеграции с внешними сервисами, где контракт задаётся не в TypeScript.

OpenAPI → Zod схемы

Более сложный уровень кодогенерации связан с OpenAPI спецификациями.

Инструменты:

  • openapi-zod-client
  • @asteasolutions/zod-to-openapi
  • openapi-typescript + кастомные трансформеры

Процесс включает два направления:

1. Генерация Zod из OpenAPI

OpenAPI описывает структуры запросов и ответов, которые затем преобразуются в Zod:

User:
  type: object
  properties:
    id:
      type: string
    email:
      type: string

Результат:

const UserSchema = z.object({
  id: z.string(),
  email: z.string(),
});

2. Генерация OpenAPI из Zod

Обратное направление позволяет использовать Zod как источник спецификации API:

import { z } from "zod";
import { extendZodWithOpenApi } from "@asteasolutions/zod-to-openapi";

extendZodWithOpenApi(z);

const UserSchema = z.object({
  id: z.string().openapi({ example: "123" }),
  email: z.string(),
});

Далее схема может быть преобразована в OpenAPI документ.

Такой подход делает Zod центральным элементом API-дизайна, а не только валидации.

Генерация API-клиентов

Кодогенерация в связке Zod часто используется для построения типобезопасных клиентов.

Zodios

Zodios реализует подход, при котором API описывается через Zod, а затем автоматически превращается в клиент:

const api = new Zodios("/api", [
  {
    method: "get",
    path: "/users",
    response: z.array(UserSchema),
  },
]);

Генерация здесь выражается не в создании файлов, а в формировании строго типизированного runtime-клиента, где:

  • запросы проверяются на уровне типов
  • ответы валидируются через Zod
  • отсутствует необходимость ручных DTO

Генерация схем из ORM

В экосистеме backend-разработки важное место занимает синхронизация базы данных и схем валидации.

Prisma → Zod

Один из популярных подходов:

prisma-zod-generator

Пример Prisma модели:

model User {
  id    String @id
  email String
  age   Int?
}

Генерация Zod:

export const UserSchema = z.object({
  id: z.string(),
  email: z.string(),
  age: z.number().optional(),
});

Такая связка позволяет:

  • синхронизировать DB и API слой
  • исключить ручное дублирование моделей
  • обеспечить единый контракт данных

Конвертация Zod → TypeScript и обратно

Несмотря на то, что Zod уже интегрирован с TypeScript через z.infer, существуют инструменты расширенной генерации:

  • генерация .d.ts файлов
  • генерация runtime-схем из типов

ts-to-zod

Инструменты типа ts-to-zod позволяют преобразовывать TypeScript интерфейсы в Zod-схемы:

interface User {
  id: string;
  email: string;
  age?: number;
}

Результат:

const UserSchema = z.object({
  id: z.string(),
  email: z.string(),
  age: z.number().optional(),
});

Такая трансформация применяется в случаях, когда:

  • типы уже существуют в legacy-коде
  • необходимо добавить runtime-валидацию без переписывания архитектуры

Автоматическая генерация валидаторов в монорепозиториях

В крупных проектах кодогенерация Zod часто встроена в сборочные пайплайны:

  • Nx
  • Turborepo
  • custom CLI генераторы

Типичный сценарий:

  1. Сервис описывает контракт в OpenAPI или GraphQL
  2. Генератор преобразует контракт в Zod-схемы
  3. Эти схемы экспортируются в shared пакет
  4. Клиенты используют их без повторной реализации

Генерация схем для GraphQL

Хотя Zod не является нативной частью GraphQL, он часто используется как слой валидации поверх резолверов.

Инструменты генерации позволяют:

  • создавать Zod-схемы из GraphQL schema
  • валидировать входные аргументы резолверов
  • описывать DTO отдельно от GraphQL SDL

Подход часто применяется в архитектурах, где GraphQL рассматривается как транспорт, а Zod — как слой доменной валидации.

Паттерны использования кодогенерации

Единый источник правды

Zod-схемы выступают центральным контрактом:

  • API
  • клиент
  • база данных
  • документация

Генерация происходит вокруг них, а не наоборот.

Слоистая генерация

OpenAPI / Prisma / GraphQL
        ↓
   Zod schemas
        ↓
 TypeScript types
        ↓
  API clients

Каждый слой может генерироваться независимо, но все они связаны через Zod.

Генерация через плагины сборщика

Инструменты типа Vite или Webpack позволяют интегрировать генерацию Zod-схем в билд:

  • prebuild step
  • watch mode генерации
  • incremental regeneration

Ограничения кодогенерации в Zod-экосистеме

Несмотря на широкие возможности, существуют структурные ограничения:

  • сложные conditional types плохо транслируются в JSON Schema
  • union-типы могут терять детализацию при обратной генерации
  • циклические зависимости требуют ручной корректировки
  • runtime-логика не всегда поддаётся генерации

Поэтому кодогенерация обычно дополняет, а не заменяет ручное проектирование схем.

Гибридные подходы

В современных архитектурах часто применяется комбинированная модель:

  • Zod-схемы пишутся вручную для доменных сущностей
  • внешние контракты генерируются автоматически
  • ORM-слой синхронизируется через генераторы
  • API-клиенты формируются из схем

Такой подход позволяет балансировать между контролем и автоматизацией, минимизируя расхождения между слоями системы.