Расширьте возможности разработчиков с помощью динамических типов
Всем привет! Этот пост основан на последнем выступлении Жана Себастьяна на Strapi Conf 2023. Ссылку на видео дам в конце поста.
JS — бэкэнд-инженер, специализирующийся на опыте разработчиков в Strapi. Он также любит TypeScript.
Убери это, Джейс.
Всем привет! Меня зовут Жан Себастьян, и я рад поделиться некоторыми мыслями о том, как вы можете улучшить свой опыт разработчика, особенно при работе с приложениями с высокодинамичными структурами контента с использованием TypeScript. Итак, без лишних слов, давайте копать.
Почему TypeScript?
TypeScript — это мощный инструмент, расширяющий возможности разработчиков благодаря многочисленным функциям. К ним относятся, помимо прочего, функции, обеспечивающие безопасность типов, предлагающие улучшенный IntelliSense и упрощающие навигацию по сложным базам кода.
Например,
- Безопасность типов: TypeScript помогает в раннем выявлении ошибок с помощью проверок во время компиляции и анализа в реальном времени в интегрированных средах разработки (IDE).
- Исследование кодовой базы: функции аннотации типов и перехода к объявлению невероятно полезны для удобочитаемости и отслеживаемости кода.
- IntelliSense: TypeScript выводит кодирование на новый уровень, предлагая руководство в реальном времени, начиная от автоматического завершения и заканчивая предложением кода.
Думайте о TypeScript как о судье в игре. Он считывает правила, т. е. типы и конфигурации, предоставленные разработчиками, и соответственно вызывает предупреждения, ошибки и выдает коды.
В совокупности это делает TypeScript огромным преимуществом в повышении производительности при одновременном снижении затрат на разработку за счет устранения большинства ошибок при запуске и проблем с истечением срока действия кодовой базы.
Однако если предположить, что TypeScript — это волшебная палочка, преобразование JavaScript в TypeScript с помощью простой операции переименования было бы наивным.
TypeScript великолепен… в большинстве случаев.
TypeScript очень хорошо работает с intellisense или проверкой типов, потому что он опирается на источник истины, типы, определенные разработчиками.
Разработчики, как правило, очень хорошо знают структуры и модели приложений; например, кто-то, разрабатывающий веб-сайт электронной коммерции, вероятно, знает, что ему понадобится модель для представления проекта, бренда и корзины, а также как соединить их, создавая ссылки и отношения, точно так же, как кто-то делает блог знать, что они имеют дело с почтовыми тегами и авторами.
Машинопись является только рефери; он читает правила, написанные разработчиками.
Здесь, в Страпи, у нас есть интересный вызов. Мы не знаем структуру контента заранее или что-то точное о нашей модели пользовательских приложений.
Таким образом, мы не можем предполагать и генерировать типы заранее, поскольку возможности будут безграничны, поскольку, как пользователь Strapi, вы можете создавать любые типы контента, которые нужны вашему приложению для вашего конкретного случая использования.
Создание общих типов — непростая задача. Как будет работать TypeScript, когда модели крайне непредсказуемы?
Во-первых, давайте рассмотрим пример получения данных. Цель состоит в том, чтобы создать универсальную функцию, которая запрашивает данную модель, чтобы получить связанный с ней контент из базы данных.
Хотя приведенный выше код является точным с точки зрения Typescript, он не очень помогает нам при разработке нашего приложения, потому что здесь у нас есть свободная проверка типов, нет автозаполнения для доступных uid или какой-либо информации о значениях, которые мы можем ожидать в ответ.
Это делает работу разработчика немного странной, и вам, вероятно, придется много работать, чтобы адаптировать типы к вашему проекту.
Чтобы исправить это, нам потребуется доступ к какой-то базе данных машинописи или реестру всех моделей, которые существуют в нашем внешнем приложении, и их uid.
Мы можем изменить наш код на следующий.
и здесь на помощь приходят реестры динамических типов.
Реестры динамических типов
Реестры динамического типа — это обычные интерфейсы, объявленные в общем модуле, которые будет экспортировать магазин Strapi.
Хотя по умолчанию он пуст, мы решили использовать возможности слияния и расширения интерфейсов, чтобы позволить вашему приложению или плагину Strapi добавлять новые определения типов в эти интерфейсы.
Например, если вы используете модель статьи в своем приложении Strapi, вы можете зарегистрировать ее в общем интерфейсе, чтобы Strapi могла использовать ее при использовании внутреннего API.
Таким образом, у нас есть база данных общих компонентов, таких как модели в нашем случае, которые используются внутренним API, а также заполняются и дополняются внешними участниками.
В конце концов, это позволяет нам писать универсальные API-интерфейсы на основе абстрактных моделей и сущностей на стороне Strapi, предоставляя при этом всю мощь автозаполнения машинописного текста и IntelliSense в пользовательских проектах, расширяющих реестры типов.
Вот схема того, что мы только что объяснили; как видите, Strapi предоставляет модуль общих реестров, содержащий множество интерфейсов.
Затем модуль и его интерфейсы расширяются внешними субъектами, такими как приложение или плагин, и затем могут использоваться кем угодно для создания пользовательских APS или просто ссылочных типов.
Хотя это решает проблему наличия точных типов и разработки мощных типизированных API, это не очень масштабируемое решение.
Необходимость писать сложные типы и вручную дополнять множество общих реестров для одного приложения — это слишком много, и в конце концов это только вызовет разочарование.
К сожалению, этот ручной процесс не масштабируется из-за связанных с ним сложностей, что приводит к плохому опыту разработчиков. Но есть решение — Автоматическая генерация Типа.
Автоматическая генерация типа.
Он состоит в том, что Strapi считывает ваши модели приложений для создания типов, которые затем дополняют динамические реестры.
Но сначала определимся с нашими потребностями.
- Это нужно сделать программно.
- Необходимо создавать типы с литеральными значениями.
- Он должен быть ремонтопригодным.
И следует избегать манипуляций со строками, таких как конкатенация и т. д., которые привели нас к открытию TypeScript Factory API.
Фабричный API TypesScript
Фабричный API TypeScript — это набор утилит, предназначенных для создания узлов TypeScript AST и управления ими. Затем узлы можно использовать для создания определений в исходном файле.
Мы преобразовали наши модели в узлы машинописного текста, используя фабричный API, создали фальшивый исходный файл из того же определения, а затем, наконец, выпустили файлы определения машинописного текста, содержащие расширение реестра и связанные типы моделей.
Здесь вы можете увидеть, что происходит, когда мы вручную запускаем генерацию типов, поскольку она создает типы для типов контента и компонентов приложения Strapi.
И здесь мы можем видеть часть того, что излучается.
Мы можем наблюдать расширение модуля хранилища и расширение реестра компонентов различными моделями.
В конце концов, мы нашли обходной путь, позволяющий пользоваться всеми преимуществами TypeScript при работе с высокодинамичными структурами контента.
Здесь мы видим, что наш предыдущий пример отлично работал с сгенерированными типами и дополненными реестрами.
Надеюсь, вам понравился этот пост JS, и мы увидимся в следующий раз.