AI Vibe Craft
← Назад к AI Vibe News

Редакция 26 апреля 2026 г.

Разборы

От JSON к TypeScript: пять способов уйти от ручного написания интерфейсов

От JSON к TypeScript: пять способов уйти от ручного написания интерфейсов.

Сырые ответы API в JSON редко превращаются в типы TypeScript «одним касанием»: неверно помеченный optional, смешение null и undefined на разных сэмплах или вывод по одному варианту ответа, когда внешний API ведёт себя по-разному — и ошибка всплывает не сразу. Зато инференс и code generation по схеме давно вшиты в рабочий цикл: в одной связке оказываются quicktype, openapi-typescript и Zod, где z.infer связывает валидатор и тип. Практический гайд на Dev.to (автор helloashish99, 25 апреля 2026) разбирает пять приёмов, типичные срывы автогенерации и ситуации, в которых ручная доводка схемы разумнее, чем слепо доверять выходу генератора. Ниже — сжатый пересказ того же материала.

Когда вручную писать типы — это не дисциплина, а источник багов

Копипаст из JSON в ручные интерфейсы в том материале сопоставляют с багами, которые долго не замечают. Перед обзором quicktype, openapi-fetch и Zod автор выделяет три группы ручных ошибок: неверно выставленный optional у поля, которое в реальном ответе исчезает; смешение null и undefined на разных образцах; жёсткий перенос одного варианта ответа, когда API ведёт себя неодинаково. На фоне инференса и code generation это читается так: если слепо довериться сгенерированной сигнатуре, цена ошибки на одном сэмпле оказывается заниженной — отсюда смысл мультисэмпла в quicktype и контрактов вместо разового снимка тела ответа. Время публикации на площадке: 25 апреля 2026, 13:19 UTC. Ориентир длительности чтения на странице Dev.to: 8 минут.

Метод 1 и 2: «раз в браузере» против продакшн-pipeline

Сначала в статье идут браузерные one-off-конвертеры; в примере назван набор на json.renderlog.in для пары JSON→TypeScript, с акцентом на клиентском исполнении. Подчёркнуто, что такой путь не годится для CI и повторяемой регенерации, если нужен одинаковый билд. Дальше — quicktype с npx и мультисэмплом, с обсуждением «шумных» union с null и флагов вроде --no-maps, --no-enums, --no-combine-classes, чтобы сузить форму сгенерированного кода. Словом workhorse в английском вводе окрестили «лошадь» для среды со скриптами в CI / CLI, в отличие от одноразовой вкладки в онлайн-конвертер.

Схема, OpenAPI и openapi-fetch: договор вместо среза ответа

Третий метод — смещение к JSON Schema и OpenAPI: json-schema-to-typescript и openapi-typescript, с аргументом в пользу контракта как источника правды, а не разового снимка тела JSON. Рядом появляется идея типизированных HTTP-клиентов и связок вроде openapi-fetch: типы на границе выводятся из схемы, и разрыв между сгенерированным клиентом и реальными ответами уже не тот, если схема стабильнее, чем снимок, снятый одним curl.

Zod, z.infer и место, где inference сидит в одном кольце с валидацией

Четвёртая ветка — Zod: валидатор на границе (HTTP, формы) и z.infer как совпадение типа с валидатором. Сцепка выглядит так: черновой Zod из JSON через JSON→Zod на json.renderlog.in, с оговоркой, что правила для нетривиальной схемы дальше всё равно дожимать вручную. Здесь вывод типа и проверка данных идут парой: сигнатуру не рисуют отдельно от валидатора — контур типа задаёт сам валидатор. Valibot и Yup в том же сюжете фигурируют как рантайм-альтернативы, без сравнения, которого нет в первоисточнике.

TypeScript → JSON Schema и пятый, обратный путь

Пятый метод — обратный вектор: ts-json-schema-generator, из TypeScript к JSON Schema, если нужно вывернуть модель, оформленную в типах, в схему для других потребителей. Как продукт цепочки TS → JSON Schema это не повторяет квартет приёмов JSON→TS, которые разобрали выше.

Пять мест, где автогенерация умной сигнатуры остаётся с глупостями

Раздел «Five mistakes auto-generation still makes» нумерует пять устойчивых сбоёв. Ниже — смысловой перенос (страница: тот же URL, обращение 25.04.2026, 22:15 UTC).

  1. Пустые массивы: в стиле never[] или, хуже, any[], если в образце roles: [] не видно структуры элементов — нужен сэмпл с элементом или доработка, например до string[].
  2. Optional и nullable: с одного { "email": null } конвейер вправе сделать слишком буквальный null вместо string | null; мультисэмпл снижает риск, но не снимает его полностью.
  3. Discriminated unions: в тексте контраст между плоским интерфейсом с кучей опциональных полей и помеченным union, который сужается в switch.
  4. Даты-строки: по проводу остаётся string, на приёме — парсинг; в Zod-цепочке упоминаются .datetime() и .transform.
  5. any/unknown в динамичных ветвях: совет — вручную просмотреть any в сгенерированном файле до коммита.

Инференс типов и автогенерация по схеме — та плоскость, на которой Dev.to подводит читателя к практике: в кратком описании поста рядом фигурируют openapi-typescript и Zod inference, в такт с развёрнутым разбором пяти методов и пяти типичных ошибок.

Масштабирование, крайние случаи и длинный хвост renderlog

Сводный production-sized план в источнике такой: источник правды в схеме, openapi-typescript в CI, рантайм-валидация (Zod / Valibot / Yup) на границе, плюс ручные типы к UI, если у формы другая природа, чем у сетевой (wire) модели. Случаи, когда не стоит автогенерировать, перечислены отдельно: стабильные крохотные payload, тяжело кастомизируемые схемы, одноразовые скрипты, где печать вручную дешевле. Финал возвращается к клиентским вспомогалкам на json.renderlog.in (сравнение JSON, схема из сэмпла, JSONPath, repair, больше языков, токен/JWT) и TL;DR — без детализации renderlog вне приведённого перечня в статье.

Источники

  • HelloAshish, From JSON to TypeScript: Five Ways to Stop Hand-Writing Interfaces, Dev.to — Dev.to (дата обращения: 25.04.2026, 22:15 UTC).