YamlBox

Генераторы кода · 6 минута чтения

От JSON до TypeScript: типы, соответствующие реальности

Самый быстрый способ получить правильные типы TypeScript для API — это сгенерировать их на основе ответа, который фактически вернул API. Написанные вручную интерфейсы описывают ожидаемую полезную нагрузку; Преобразование JSON в TypeScript описывает имеющуюся у вас полезную нагрузку, а разрыв между этими двумя значениями – это то место, где происходят сбои во время выполнения.

Обновлено

Почему рукописные шрифты смещаются

Интерфейсы, написанные на основе документации или памяти, обычно оптимистичны. Они отмечают все присутствующее, предполагают, что поле, допускающее значение NULL, всегда присутствует, и незаметно пропускают вложенный объект, который появляется только на премиум-аккаунтах. Затем TypeScript применяет форму, которую сервер никогда не обещал, и первый `undefined` появляется в рабочей среде, а не во время компиляции. Генерация на основе реальных ответов меняет процесс: компилятор проверяет наблюдаемую форму, а не ожидаемую.

Чтение сгенерированного файла

Полезное преобразование называет вложенные объекты по их ключам, сохраняет типы элементов массива нетронутыми и явно выражает неопределенность. Обратите внимание на три маркера, которые несут в себе все значение:

                export interface Order {
  id: string;
  total: number;
  coupon?: string;            // absent in some responses
  shippedAt: string | null;   // present but null until shipped
  items: Array<OrderItem>;
}
              

Разница между `coupon?: string` и `shippedAt: string | null` не косметическая. Необязательно означает, что ключ может отсутствовать; null означает, что ключ не имеет значения. API выполняют и то, и другое, часто с одной и той же полезной нагрузкой, и их объединение приводит к проверке нуля в коде, который предполагает строку.

Используйте более одного образца

Один ответ отмечает все необходимое. Вставьте два или три ответа — в идеале один из пустой учетной записи и один из полной — и дополнительные ключи проявятся: поле, отсутствующее в любом образце, станет `?`, а поле, которое иногда имеет нулевое значение, станет объединением с `null`. Это самое дешевое из доступных обновлений корректности, и именно по этой причине сгенерированные типы следует перегенерировать при изменении API, а не записывать один раз.

Никогда не позволяйте сгенерированному интерфейсу быть единственным описанием вашего API. Держите рядом с ним тест схемы или контракта, чтобы при изменении сервера произошла ошибка сборки, а не пользовательского сеанса.

Где принадлежат типы

  • Специальная папка `types/` или `api/`, не разбросанная по компонентам.
  • Один файл для каждой конечной точки или ресурса с комментарием, в котором указывается конечная точка и дата ее записи.
  • Примечание о регенерации: какой вызов создал полезную нагрузку, чтобы следующий человек мог ее повторить.
  • Экспорт используется как слоем выборки, так и компонентами, поэтому изменение нарушает ровно одно место.

Включите строгий режим

Сгенерированные типы окупаются только при включенном `strict`, поскольку именно это делает необязательный ключ реальной ошибкой при прямом доступе. Соедините сгенерированные интерфейсы с `unknown` на границе выборки и сузьте перед использованием: `JSON.parse` возвращает `any`, поэтому приведение к сгенерированному интерфейсу должно быть точкой, где вы проверили, а не там, где вы надеетесь.

Генерируйте из полезных данных, которые вы бы не загрузили.

Ответы API являются наиболее конфиденциальными JSON, с которыми работает большинство разработчиков: данные учетной записи, заказы, токены. Выполнение преобразования JSON в TypeScript в браузере означает, что полезные данные анализируются локально и никогда не передаются, поэтому вы можете вставить реальный ответ, не редактируя его предварительно, и инструмент продолжит работать в автономном режиме.

от JSON до TypeScript — часто задаваемые вопросы

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

Включите второй образец, в котором этот ключ отсутствует, и выполните регенерацию — тогда преобразователь выдаст `key?: type`. Вывод помечает поле как необязательное только тогда, когда есть доказательства его отсутствия, поэтому одной выборки никогда не бывает достаточно для контракта.

Должен ли я использовать интерфейс или тип для сгенерированных типов JSON?

Оба работают для форм объектов; Интерфейсы являются традиционными для моделей API, поскольку их можно расширить и выдавать более четкие сообщения об ошибках. Важным выбором является режим `strict`, а не то, какое ключевое слово вы выберете.

Могу ли я преобразовать JSON в TypeScript без отправки данных на сервер?

Да. Конвертер на этом сайте генерирует интерфейсы на самой странице, поэтому ответ никогда не покидает ваш браузер, а преобразование продолжает работать даже при отключении сети.

Инструменты, упомянутые в этом посте

Просмотрите полный список инструментов 19

Еще статьи для чтения

6 минута чтения

Схема от JSON до JSON: от образца полезной нагрузки до

Преобразуйте схему JSON в JSON в браузере: сделайте вывод о черновике из реальной полезной нагрузки, затем ужесточите обязательные поля, форматы и перечисления, а также ограничения на вывод.

Все 19 публикации →