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;   // може бути відсутнім
  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 змінюється без повторної генерації.

Додаткове читання