Як працює виведення JSON до TypeScript
Виведення — це один прохід по розібраному JSON-дереву. Інструмент читає кожне значення, вибирає для нього TypeScript-тип, а потім записує один інтерфейс на кожен знайдений об'єкт.
- Розібрати зразок JSON нативним парсером браузера і відхилити некоректне введення з підказкою рядка/стовпця.
- Визначити TypeScript-тип для кожного значення —
string,number,boolean,null, масив або вкладений об'єкт. - Дати кожному вкладеному об'єкту ім'я інтерфейсу, похідне від ключа батьківської властивості (тобто
user.addressстає інтерфейсомAddress). - Злити типи елементів по кожному масиву, щоб список
{id: 1}і{id: 2, label: "x"}давав об'єднання з правильними опціональними полями. - Застосувати ваші параметри (interface проти type, readonly, optional-nullable) і вивести оголошення у порядку залежностей, щоб файл компілювався без прямих посилань.
Навіщо генерувати TypeScript-типи з JSON?
- Більшість помилок форми можна виявити на етапі компіляції, якщо тип відповіді записаний. Виведення інтерфейсу з реального навантаження робить більшу частину роботи за вас, а режим `strict` виявляє поле, яке документація забула згадати.
- Поєднання виведених інтерфейсів з runtime-валідатором, таким як Zod або io-ts, дає одній і тій самій формі два завдання: автодоповнення в редакторі під час розробки та помилка 400 на межі, коли продакшн надсилає щось несподіване.
- Мовний сервер TypeScript відображає лише ті поля, про які знає. Після імпорту виведеного інтерфейсу автодоповнення працює, щойно ви вводите крапку — більше жодного приведення `as any` на відповіді та розчарованого grep по репозиторію.
- Якщо ви збираєтеся писати специфікацію OpenAPI, виведений інтерфейс є швидким першим чернетком схеми відповіді. Ручні приклади та обмеження ще знадобляться, але імена властивостей і типи вже правильні.
Типові застосування
Виведення найбільш корисне, коли реальне навантаження існує, а схеми немає.
- Типізація вебхук-навантажень від сторонніх постачальників (Stripe, GitHub або Twilio) перед написанням обробника.
- Завантаження типів для внутрішнього REST API, щоб фронтенд-команда могла починати кодувати проти нього в той самий день, коли з'являється бекенд.
- Генерація відправної точки для схеми Zod, io-ts або Valibot з спостережуваної відповіді API.
Як виглядає вивід?
Для зразка JSON-документа та кореневого імені генератор виробляє дерево інтерфейсів — по одному на кожен вкладений об'єкт. Для наведеного нижче введення з кореневим ім'ям User:
Вставте {"id":1,"name":"Alice","tags":["a","b"],"address":{"city":"Paris"}} з кореневим ім'ям User і генератор виведе:
export interface User {
id: number;
name: string;
tags: string[];
address: Address;
}
export interface Address {
city: string;
}
Зверніть увагу, що address виокремлено в окремий іменований інтерфейс — це вивід у порядку залежностей. Той самий JSON зі стилем оголошення type дасть export type User = {...}; з увімкненим перемикачем readonly кожна властивість отримає модифікатор readonly.
Параметри генератора
Стиль оголошення
Вибирайте interface (стандартна TypeScript-ідіома для форм об'єктів) або type (зручний, якщо пізніше знадобляться mapped-типи, умовні типи або перетини). Обидва мають однакову поведінку у виконанні; вибір — це перевага стилю кодування.
Опціональні nullable-поля
Коли зразкове значення є null, тип поля стає T | null. Увімкнення цього параметра також додає модифікатор ?, щоб поле було опціональним з боку TypeScript — корисно, коли API іноді повністю пропускає ключ замість повернення null.
Модифікатор readonly
Додає readonly до кожного оголошення властивості, щоб виведений інтерфейс відповідав незмінній моделі даних. Зручно для зрізів стану Redux, заморожених відповідей API або будь-де, де ви хочете, щоб компілятор сигналізував про випадкові мутації.
Чи підтримуються вкладені об'єкти та масиви?
Так. Кожен вкладений об'єкт стає іменованим інтерфейсом, похідним від ключа батьківської властивості, а масиви виводять тип елемента з їхнього вмісту. Масиви об'єктів отримують інтерфейс на кожну форму об'єкта, з типами-об'єднаннями там, де форми не збігаються.
Як виводяться опціональні поля?
Увімкніть перемикач «Позначити nullable-поля опціональними» і будь-яке поле, зразкове значення якого є null, отримає модифікатор ? на ключі та | null у типі. Без цього перемикача поле залишається обов'язковим, а тип буде просто T | null.
Чи підтримуються дискримінаційні об'єднання?
Базові типи-об'єднання виходять, коли масив містить елементи з різними формами або коли поле несе і значення, і null. Повне виведення дискримінаційних об'єднань (вибір type або kind як тегу і розбивка варіантів) потребує кількох зразків — це заплановано, але ще не в поточній збірці.
Чи можна виводити типи з кількох зразків JSON?
Поки що ні — поточний інфератор читає один зразок за раз. Якщо у вас два навантаження, що мають спільний інтерфейс (наприклад, ендпоінт списку і ендпоінт окремого елемента), практичний спосіб обійти це — злити їх в один масив, згенерувати з нього і перейменувати отримані типи-об'єднання. Виведення з кількох зразків є в дорожній карті, оскільки це єдиний спосіб виявити поля, присутні в одній відповіді та відсутні в іншій.
Вставте навантаження, назвіть корінь, скопіюйте інтерфейси. Увесь конвеєр працює у вашому браузері, тому API до релізу або підписане тіло вебхука залишається на вашому пристрої.