JSON Toolkit

Генерация типов TypeScript из Schema

Главное: json-schema-to-typescript и quicktype выдают .d.ts одной командой, но это черновик: опциональность, объединения, additionalProperties и даты требуют ручного прохода.

Средний~4 мин чтенияОпубликовано 2026-10-30Обновлено 2026-10-30
Генерация типов TypeScript из JSON Schema

Главное: генерируйте через json-schema-to-typescript или quicktype, затем вручную исправляйте опциональность, объединения, additionalProperties и даты; держите Schema источником, а типы — выводом, что обеспечивается шагом types:check в CI.

Одна команда даёт вам файл. Она не даёт вам корректные типы.

Однострочник

npx json-schema-to-typescript schema.json > src/types/order.d.ts

Он обрабатывает $ref, allOf, oneOf, anyOf и превращает description в JSDoc. Для пакетной генерации с баннером и выбранным style вызывайте его Node API из небольшого build-types.mjs.

quicktype — альтернатива, и он также может выводить схему из образца JSON:

npx quicktype -s schema schema.json -o order.ts --lang typescript

Четыре вещи, которые нужно исправить после

Опциональность. Всё, что не в required, становится ?. Но «всегда присутствует, может быть null» и «может отсутствовать» — разные контракты:

interface Order {
  remark?: string | null;   // may be missing
  status: string;
}

Если бэкенд всегда отправляет remark: null, уберите ? и перестаньте заставлять каждого потребителя защищаться от undefined.

Недискриминированные объединения. oneOf обычно становится A | B, которое TypeScript не может сузить без литерального поля. Добавьте фиксированное свойство type каждой ветке в Schema.

additionalProperties. Опущенный или true иногда даёт [k: string]: unknown, иногда any. Первый безопасен, второй молча отключает проверку типов для всего объекта.

Форматы дат. format: "date-time" — это строка в передаче. Отображение в Date означает, что вы также должны десериализовать, иначе значение во время выполнения остаётся строкой, пока тип лжёт.

Держите направление фиксированным

Schema — источник, типы — вывод. Генерировать Schema из написанных вручную типов допустимо только если регенерация обязательна и обеспечена в CI — иначе обе стороны дрейфуют и никто не знает, какая авторитетна.

Поместите это в конвейер

"types:gen": "json2ts -i schemas/ -o src/types/generated",
"types:check": "pnpm types:gen && git diff --exit-code src/types/generated"

types:check — та часть, которая важна: измените Schema без регенерации, и CI падает.

Вопросы и ответы

Почему сгенерированный файл содержит any?

Обычно это происходит от additionalProperties, равного true или опущенного, что некоторые генераторы отображают в [k: string]: any. Замените его на unknown или явные поля, потому что any отключает проверку типов для всего объекта.

Как исправить необязательные поля после генерации?

Всё вне required становится ?, но «всегда присутствует, может быть null» отличается от «может отсутствовать». Если бэкенд всегда отправляет поле, уберите ?.

Должен ли CI падать, когда Schema и типы расходятся?

Да. Скрипт types:check, который регенерирует и запускает git diff --exit-code, ломает сборку, как только Schema меняется без регенерации.

Дополнительное чтение