Сгенерировать TypeScript-типы и интерфейсы по JSON: вложенные объекты, массивы, объединения, необязательные поля. Несколько образцов — общая схема.
Типы по чужому API пишут руками, сверяясь с документацией и ответами сервера. Работа механическая: посмотреть на поле, определить его тип, не забыть про вложенный объект, решить, что делать с полем, которое приходит не всегда. На десятке полей это минуты, на большом ответе — часы, и всё это время в код легко закрадывается ошибка: поле объявлено обязательным, хотя его нет в половине ответов, а тип у элемента массива взят с первого попавшегося примера. Сгенерированные по настоящим данным типы такой ошибки не содержат — они описывают ровно то, что в данных есть, и не больше.
Главное здесь — не перевод одного объекта в интерфейс, а построение общей схемы по нескольким образцам. Каждый образец превращается в набор форм, формы соединяются: одинаковые сливаются, разные образуют объединение, а ключ, которого не хватает хотя бы в одном образце, помечается знаком «?». Поэтому в результат стоит вставлять не один ответ, а два-три разных: от них зависит, какие поля окажутся необязательными и какие объединения появятся. Отчёт под результатом показывает и то, и другое: таблицу необязательных полей с номерами образцов, где ключа не было, и таблицу объединений со значениями, из которых каждое собрано.
Всё считается в браузере: JSON разбирается и типы строятся на JavaScript в самой странице, образцы никуда не отправляются и не сохраняются. Рядом есть инструмент для Python — «JSON в Python» в разделе «Разработчику»: он делает то же самое для датаклассов и моделей Pydantic. Если же JSON нужно просто привести в читаемый вид или проверить, для этого есть «Проверить JSON онлайн» в разделе «Данные и форматы».
Вставьте JSON в поле слева — типы появятся справа сразу, по мере ввода, нажимать ничего не нужно. По умолчанию корневой объект становится интерфейсом `Root`, вложенные объекты — отдельными объявлениями: объект в поле `address` превращается в `Address`, а элемент массива `orders` — в `Order`. Имя корневого типа можно поменять в настройках, если в вашем проекте принято, например, `ApiResponse`. Готовый код копируется одной кнопкой или скачивается файлом `.ts`.
Один образец описывает только то, что в нём есть: каждый ключ в полученном типе будет обязательным, а поля, которого в этом ответе сервера не оказалось, в типе не будет вовсе. Несколько образцов дают общую схему: поля складываются, а ключ, подтверждённый не всеми образцами, помечается знаком «?» и в отчёте видно, в каких образцах его не было. Образцы разделяются строкой из трёх и более дефисов — `---` на отдельной строке. Двух-трёх разных ответов обычно достаточно, чтобы описать ответ целиком.
Знак «?» ставится ключу, которого не было хотя бы в одном образце при том, что сам объект в этом образце был. Читается это так: ключ может прийти, а может и не прийти, и обращаться с ним нужно как с возможным `undefined` — например, через `?.` или проверку. В отчёте под результатом перечислены все такие поля и указаны номера образцов, в которых ключа не было: если образец был один, необязательных полей не будет ни одного, потому что сравнивать не с чем.
Объединение появляется там, где в разных образцах у одного и того же места оказались значения разной формы: `null` в одном и `"igor@example.com"` в другом дают `string | null`, число `101` против строки `"102"` — `number | string`. Так же собираются массивы из разнородных элементов: `[1, "два"]` становится `(number | string)[]`. Под результатом есть таблица объединений, где для каждого указано, из каких именно значений оно собрано, — по ней видно, случайное это расхождение в данных или постоянное, и нужно ли поправить источник.
На смысл типов выбор не влияет, разница в записи. `interface` — привычное объявление объекта, его удобно расширять через `extends`. `type` — псевдоним: им описывают не только объекты, но и массивы, и объединения. Поэтому в режиме `interface` инструмент объявляет объекты через `interface`, а корень, который объектом не является (массив или объединение), всё равно приходится объявлять через `type` — о таком отступлении он сообщает отдельной строкой под результатом. Если не знаете, что выбрать, берите `type`: он покрывает все случаи одинаково.
`camelCase` приводит имена полей к привычному виду: `user_name` и `user-name` становятся `userName`. Кавычки остаются там, где имя ключа не годится в идентификатор: `"2fa"`, `"user-name"`, ключ с пробелом. TypeScript такие имена допускает, и обращение к полю в коде остаётся прежним — `data["user-name"]`. Ключи, различающиеся только регистром (`id`, `Id`, `ID`), никогда не схлопываются в один: и в режиме «как в JSON», и после приведения к camelCase каждый из них остаётся отдельным полем.
Языком на выходе: вход у обоих инструментов общий — те же образцы JSON. Здесь из них собираются объявления TypeScript (`interface` или `type`), и рядом есть отчёт о необязательных полях и объединениях: готовый код вставляют в `.ts`-файл проекта. Инструмент «JSON в Python» (/tools/developer/json-to-python) делает ту же работу для другого языка — печатает датаклассы, модели pydantic v2 или TypedDict, — и у него есть обратный ход: по уже написанному классу он собирает пример JSON. Выбор диктует язык проекта, а не данные: если проект на TypeScript — оставайтесь на этой странице, если на Python — разница только в этом.
Нет. Разбор JSON и построение типов выполняются на JavaScript прямо в браузере: ни один образец никуда не передаётся, не сохраняется и не попадает в логи. Это важно, когда типы снимают с ответа внутреннего API: в примерах бывают настоящие имена, почты, идентификаторы и токены. Инструментом можно пользоваться офлайн, а страницу — сохранить и открыть с диска.