Как использовать typescript в react
⚛️ 12 советов по внедрению TypeScript в React-приложениях
Сергей Кравченко
Зачем использовать TypeScript в React?
React – это JavaScript-библиотека с открытым исходным кодом для создания пользовательских интерфейсов, а TypeScript – типизированное надмножество JavaScript. Объединяя их, мы создаем пользовательские интерфейсы, используя типизированную версию JavaScript. Это означает большую безопасность и меньшее количество ошибок, отправляемых во внешний интерфейс.
Не существует единственного правильного способа написания кода React с использованием TypeScript. Как и в случае с другими технологиями, если ваш код компилируется и работает, вы, вероятно, что-то сделали правильно.
Подготовка компонентов к совместному использованию с помощью TypeScript
Bit.dev стал популярной альтернативой традиционным библиотекам компонентов, поскольку он предлагает способ собрать и поделиться отдельными компонентами из любой кодовой базы.
Создавая проекты с использованием React с TS, вы убедитесь, что ваши компоненты легко понятны другим разработчикам. Это отличный способ написать поддерживаемый код и оптимизировать совместную работу команды.
Настройка проекта и tsconfig.json
Самый быстрый способ запустить приложение React/TypeScript – использовать create-react-app с шаблоном TypeScript:
tsconfig.json это файл конфигурации TypeScript. Файл содержит первоначальные настройки, ниже приведем несколько параметров с пояснениями:
Enums
Enums определяет набор связанных констант как часть единой сущности.
Интерфейсы и типы
Что следует использовать – интерфейсы или псевдонимы типов? Хотя эти сущности концептуально различны, на деле они очень похожи:
Единственная функция интерфейсов, которую не делают псевдонимы типов – это объединение деклараций.
Расширение элементов HTML
Иногда ваши компоненты работают как собственные HTML-элементы. В таких случаях лучше определить тип компонента как собственный элемент HTML или его расширение.
Типы событий
React имеет собственный набор событий, поэтому вы не можете напрямую использовать события HTML. Однако у вас есть доступ к событиям пользовательского интерфейса. Убедитесь, что ссылаетесь на них напрямую или просто не забудьте импортировать их из React следующим образом:
Мы также можем использовать для ограничения элементов Generics с конкретным обработчиком событий.
Также можно применять объединения, чтобы разрешить повторное использование обработчика несколькими компонентами:
Определение интегрированного типа
Стоит упомянуть файлы index.d.ts и global.d.ts в React. Оба они устанавливаются, когда вы добавляете React в свой проект. Эти файлы содержат определения типов и интерфейсов: чтобы понять свойства или доступность конкретного типа, вы можете открыть эти файлы и просмотреть их содержимое.
index.d.ts » data-src=»https://media.proglib.io/posts/2021/01/20/bf2cf9687a65d39e7bd4506bfdbd507a.png» > index.d.ts
ESLint/Prettier
Чтобы гарантировать, что ваш код соответствует правилам проекта, а стиль согласован, рекомендуется настроить ESLint и Prettier :
Расширения и настройки кода VS
Следующий шаг по улучшению – автоматическое исправление и предварительная настройка кода при сохранении.
Установите ESLint и Prettier для VS Code. Это позволит ESLint легко интегрироваться с вашим редактором.
Вы можете принудительно установить тип или интерфейс начального значения состояния, например, так:
Однако, если начальное значение для вашего хука потенциально может быть null, то приведенный выше код не сработает. Для этих случаев TypeScript позволяет установить дополнительный тип:
Обработка событий формы
Расширение свойств компонентов
Можно расширить свойства, объявленные для одного компонента, и задействовать их в другом. Давайте сначала посмотрим, как использовать type:
Если вы использовали interface, то можно применить extends, чтобы расширить его, но придется внести пару изменений:
Сторонние библиотеки
Мы часто включаем сторонние библиотеки в проекты React и TypeScript. В таких случаях стоит посмотреть, есть ли пакет @types с определениями типов:
Итоги
Постепенно вводим TypeScript в ваш проект на React
В последнее время в области front-end особую популярность приобретает комбинация React+TypeScript. Соответственно, возрастает актуальность грамотной миграции с JavaScript на TypeScript, желательно в сжатые сроки. Сегодня мы хотели бы обсудить с вами именно эту тему.
Как безопасно собирать и вводить компоненты React TypeScript в ваш проект React JS.
Почему может потребоваться миграция с JS на TS? Причин на то может быть огромное множество, но суть не в этом. (Гипотетический) факт заключается в следующем: вам необходимо приступить к использованию TypeScript, и нужен легкий путь внедрения его в ваш проект. Мало того, все это нужно как-то сделать, не нарушив структуры всего имеющегося кода, и убедив команду в необходимости такого перехода.
Здесь будет продемонстрирован постепенный рефакторинг: как встраивать компоненты React в другую базу кода, а затем при помощи Bit безопасно вводить их в уже работающее приложение React на JavaScript.
Безопасное встраивание компонентов TS в проект на JS при помощи Bit
Существует множество способов перейти с React JS на React TS. Суть данной статьи – показать, как это делается поступательно. Аналогичный метод применим и в других случаях.
Базовая идея заключается в том, чтобы выжать максимум из компонентов React + при помощи Bit изолировать их друг от друга в собственной среде разработки Bit. В совокупности это позволяет собирать компоненты TS и безопасно вводить их в полнофункциональное приложение React JS.
Bit – это опенсорсный инструмент для извлечения компонентов из репозиториев Git. Bit позволяет собирать компоненты TS вне проекта, написанного на JS, выделяя под каждый автономную изолированную среду разработки, которая может работать и в других проектах, независимо от их конфигураций. Затем вы можете просто версионировать и «бит-импортировать» эти компоненты в ваш проект на JS, и они будут работать.
Наряду с Bit существует Bit.dev – удаленный хаб, в котором можно хранить эти компоненты, чтобы затем использовать повторно. Мы будем держать в Bit.dev компоненты TS, а оттуда станем вводить их в наш проект на React JS.
Пример: поиск разделяемых компонентов React в bit.dev
Пример использования
Для целей этой статьи разберем пример, который в мире фронтенда сравним с классическим “hello world”: речь пойдет о приложении для планирования дел.
Не волнуйтесь, я не собираюсь рассказывать вам, как написать такое приложение для React. Предполагаю, вы уже умеете это делать и, будем честны, тема уже далеко не новая, так что увольте.
Но я воспользуюсь вот этим приложением в качестве примера – можете с полным правом делать его форк или, как минимум, откройте ссылку и посмотрите весь его код.
Данная база кода состоит из следующих компонентов:
TodoList: это главный компонент, отображаемый в форме поля для ввода текста с самой обычной кнопкой. Все находится в форме, после отправки которой текст добавляется в список, поддерживаемый основным приложением. Код этого компонента очень прост:
TodoItems: очень простой списковый компонент, используемый для вывода внутреннего списка элементов, добавленных через предыдущий компонент. Каждый из элементов кликабелен, и после нажатия на него он удаляется из списка. Код также весьма прост:
В обоих случаях соответствующие методы принимаются как свойства (Props) из главного компонента App. Полный код этого компонента приведен здесь.
Согласен, это приложение очень простое, но, еще раз подчеркну, потенциально на его месте может быть любое приложение React, над которым вы работаете в настоящий момент – и внезапно получаете задачу приступить к миграции на TypeScript. Что же делать?
Вводим TypeScript
Итак, в качестве примера предположим, что нам поручено добавить кнопку-переключатель (toggle) к каждому компоненту в нашем списке дел. После нажатия на элемент его необходимо переключить в фоновом режиме.
Ничего сверхъестественного, но, как вы помните, нас в данном случае интересует процесс, а не код как таковой.
Итак, мы не будем пытаться добавлять TypeScript в уже имеющийся у вас настроенный проект, чтобы случайно не сломать имеющуюся у вас сборку на несколько жней, а создадим совершенно новый проект, воспользовавшись чистым TypeScript:
Обратите внимание: для использования npx нужна только новая версия NPM, и она включается в процесс установки в версии 5.2.0 и выше.
Точно как и ранее, в таком случае создается шаблон для проекта, но на этот раз в качестве базового языка мы используем TypeScript.
Плюс простой компонент-переключатель, пригодный для вставки в другой проект, не привнося при этом дополнительных зависимостей. Если вам интересно, как это делается, почитайте следующую статью о том, как писать компоненты для многократного использования.
Теперь, когда этот компонент написан, можно воспользоваться Bit (это опенсорсный инструмент для версионирования и публикации отдельных компонентов), чтобы извлечь данный конкретный компонент и поделиться им, чтобы впоследствии его можно было импортировать из нашего проекта, основанного на JavaScript.
Так вы сконфигурируете ваш проект и настроите в нем новый компонент Toggle (переключатель) таким образом, чтобы его можно было разделять с другими проектами. Но, прежде, чем сможете сделать это на практике, вам необходимо залогиниться в Bit.dev (это хаб компонентов — сайт с реестром и документацией, дополняющий Bit в качестве площадки для публикации и предварительного просмотра компонентов).
Войдя в систему, просто создайте новую коллекцию под названием “toggler”, сделайте ее публичной, а затем в окне терминала выполните следующую команду:
Если “user-name” – действительно ваше имя пользователя, то в результате будет экспортирован компонент, и вы сможете увидеть его на Bit.dev. Он должен будет выглядеть примерно так:
Например, здесь я обновил мой файл-образец, добавив пояснения о том, как использовать компонент Toggler (только не забудьте нажать кнопку “Save”, когда закончите!):
Теперь давайте рассмотрим, как импортировать этот новый компонент в ваше собственное React-приложение на основе JS.
Импорт внешнего компонента
Bit берет на себя компиляцию вашего кода TypeScript в JavaScript благодаря добавленному нами компилятору. Это решает все наши проблемы, и все, что нам осталось – добавить этот компонент в ваш проект в качестве зависимости.
Для всех целей я использовал здесь Yarn, но вы с тем же успехом могли бы воспользоваться NPM, все, что для этого нужно:
В моем случае этот код превращается в:
Таким образом ваш компонент TypeScript (уже скомпилированный в JavaScript) включится в проект, и вы сможете ссылаться на этот компонент их вашего кода следующим образом:
Обратите внимание на строку 2, где я импортирую внешний компонент, который собираюсь использовать в составе оператора возврата. Ничего сложного, не требуется вносить никаких дополнительных конфигурационных изменений ни в вашем проекте, ни где бы то ни было.
Поздравляю, теперь у вас есть рабочий проект, в котором используется как TypeScript, так и JavaScript, потенциально этого можно было сделать так, что вы бы этого даже не заметили!
Как я уже упоминал выше, полный код проекта выложен на GitHub!
Заключение
Если вас интересует миграция на TypeScript, либо вы просто хотите с ней поэкспериментировать и посмотреть, как она сработает, то именно таким образом удобно постепенно вводить язык в существующий проект, не рискуя обрушить весь процесс сборки.
Typescript + React. Быстрый старт.
Содержание
React
Итак, я думаю, что все знают о React ’е. Нет смысла рассказывать подробности, если вы не в курсе, что это за покемон — вряд-ли вам будет полезна эта статья. Но если вы все таки хотите ознакомиться со статьей — бегом читать доку и только после этого возвращаться к статье.
Typescript
Создание проекта
Итак, начать стоит с создания проекта. Для создания простого (ознакомительного) проекта на React+TS рекомендую воспользоваться тулой create-react-app с параметром:
Работа с компонентами
Этот простой компонент без использования typescript будет написан так:
И тут мы сразу же встречаем несколько проблем:
TS позволяет избегать простейших ошибок с типами данных, которые проходят через ваше приложение, а также позволяет структурировать и строго определять входные и выходные параметры ваших функций(читай Компонентов, сторов и всего остального)
Работа со стором
Далее следует простое объявление action creator’ов. Это простые функции, возвращающие экшены. Благодаря типизации( CounterAction ) мы придерживаемся одинакового вида всех action creator’ов.
И, наконец, редьюсер:
Работа с API
Преимущества TS
Если вы разрабатываете или собираетесь разрабатывать большой проект с длительной поддержкой — TS для вас must have Пусть он и не принесет много профита на старте, но спустя некоторое время рефакторить и разрабатывать приложение будет гораздо проще. Конечно, на TS тоже можно говнокодить, но делать это гораздо сложнее, поскольку сам язык регулярно бьет тебя по рукам и не дает писать плохой код. TS оградит вас от примитивных багов и ошибок и добавит вашему проекту уверенности. Но, не стоит забывать, что typescript помогает только на этапе разработки. После компиляции он полностью исчезает и в runtime работает старый-добрый JS со всеми его плюсами и минусами. Если вы гонитесь за качетсвом кода и имеете достаточное количество времени на изучение и внедрение технологии — Typescript ваш выбор!
Если вы решили использовать Typescript, но исключили из workflow юнит-тестирование — это очень плохой подход. Лучше всегда выбрать тесты, нежели Typescript, поскольку Typescript проверяет ваш код, а тесты проверяют бизнес-логику, что гораздо важнее!
Недостатки
Но, как мы все знаем, серебряной пули не существует и у TS также есть свои недостатки:
Заключение
Использование Typescript с React – руководство для новичков
Друзья, в преддверии выходных хотим поделиться с вами еще одной интересной публикацией, которую хотим приурочить к запуску новой группы по курсу «Разработчик JavaScript».
Потратив последние несколько месяцев на разработку приложений на React и библиотек с использованием Typescript, я решил поделиться некоторыми вещами, которые узнал за это время. В этом руководстве я расскажу вам про шаблоны, которые я использую для Typescript и React в 80% случаев.
Стоит ли изучать Typescript для разработки приложений на React? Стоит, еще как стоит! Для себя я осознал на практике, что строгая типизация приводит к написанию гораздо более надежного кода, быстрой разработке, особенно в крупных проектах. Сначала вы, вероятно, будете разочарованы, но по мере работы вы обнаружите, что хотя бы минимальный шаблон действительно будет очень кстати.
И если вы застряли на чем-то, помните, что вы всегда можете типизировать что- нибудь как any. Any – ваш новый друг. А теперь перейдем непосредственно к примерам.
Ваш базовый компонент react с typescript
Как же выглядит стандартный компонент react на typescript? Давайте сравним его с компонентом react в javascript.
А теперь версия на typescript:
Заголовок prop остается необязательным, в то время как все еще требуется prop наследника. Мы экспортировали наш интерфейс на случай, если другому компоненту понадобится на него ссылка.
Расширение стандартных атрибутов HTML
Обработка событий
Мы можем типизировать обработчики событий, чтобы убедиться, что аргумент события имеет правильный тип. Пример ниже демонстрирует различные способы достижения этой цели:
Не знаете, какую сигнатуру аргумента использовать? В редакторе наведите курсором на соответствующее свойство обработчика событий.
Использование дженериков с компонентами react
А теперь давайте представим, что у вас есть компонент, который может принимать массив любого типа. Дженерики похожи на отправку посылки по почте. Курьер (наш компонент) не должен знать содержимое посылки, которую вы отправляете, но отправитель (родительский компонент) ожидает, что получатель получит содержимое, которое он отправил.
Мы реализуем это так:
Немного странный пример… тем не менее он демонстрирует суть. Компонент принимает массив элементов любого типа, проходит по нему и вызывает функцию children как рендер функцию с элементом массива. Когда наш родительский компонент предоставляет колбэк рендера как наследника, элемент будет типизирован правильно!
Типизация хуков (hooks)
Типизация редуктора
С редуктором немного сложнее, но если он правильно типизирован, то это замечательно.
Использование typeof и keyof чтобы типизировать варианты компонента
Предположим, что нам нужна кнопка, которая может иметь различный внешний вид, каждый из которых определен в объекте с набором ключей и стилей, например:
Эти примеры помогут вам пройти 80% пути. Если вы застряли, то очень часто стоит
просто взглянуть на существующие примеры с открытым исходным кодом.
Ну и по устоявшейся традиции ждем ваши комментарии.
React TypeScript: Основы и лучшие практики
Mar 24, 2020 · 7 min read
Подготовка к работе
create-react-app с TypeScript
Если вы предпочитаете Yarn, используйте следующую команду:
Обратите внимание, что мы не используем приложение напрямую, а применяем инструменты, которые загружают последнюю версию приложения при необходимости.
Основы
Интерфейсы
Одним из множества преимуществ TypeScript является доступ к конструкциям, которые позволяют определять интерфейс компонентов и других сложных объектов, используемых с ними, таких как форма объекта Props (количество свойств и их типов).
В приведенный выше код необходимо добавить 3 свойства:
Обратите внимание, что мы “расширили” тип FC (функциональный компонент) с помощью собственного пользовательского интерфейса. Благодаря этому функция получает все общие определения функциональных компонентов, такие как prop и тип return, которые должны быть присвоены JSX.Element.
Ес л и вы проигнорируете одно из них или отправите несовместимое значение, компилятор TypeScript и IDE (при условии, что вы используете специфичную для JavaScript IDE, такую как Code) уведомят вас об этом. Вы сможете продолжить работу только после исправления ошибки.
Лучший способ определить элемент ExtendedButton — расширить нативный тип HTML-элемента button следующим образом:
Также обратите внимание, что при работе с Bit.dev или react-docgen для автоматической генерации документов потребуется следующий синтаксис:
(Прямое определение props можно выполнить с помощью: IButtonProps в дополнение к определению компонента с :React.FC )
Перечисления (Enums)
Как и в случае с интерфейсами, перечисления позволяют определять набор связанных констант как часть единой сущности.
Импорт и использование перечислений:
Обратите внимание, что в отличие от интерфейсов или типов, перечисления переводятся на простой JavaScript. Например:
Код выше преобразуется в следующее:
Интерфейсы и псевдонимы типов
Многие новички в TypeScript часто сталкиваются с такой проблемой, как использование интерфейсов или псевдонимов типов для различных частей кода. Официальная документация не дает точного ответа по этой теме.
Несмотря на то, что теоретически эти сущности различны, на практике они очень схожи:
2. Могут использоваться для определения формы объектов.
3. Могут быть реализованы одинаково.
Единственная дополнительная функция интерфейсов — это “объединение описаний”, т. е. вы можете определить один и тот же интерфейс несколько раз, и с каждым определением свойства объединяются:
Дополнительные типы для props
К преимуществам использования интерфейсов можно отнести возможность применять свойства props для компонентов. Тем не менее, благодаря дополнительному синтаксису, доступному в TypeScript, можно также определить дополнительные props. Например:
Хуки — это новый механизм React для взаимодействия с некоторыми функциями (например, состоянием) без необходимости определять класс.
Добавление проверки типа в хуки
Благодаря проверке типа в TypeScript можно реализовать тип (или интерфейс) начального значения состояния следующим образом:
Нулевые значения для хуков
Общие компоненты
Подобно общим функциям и интерфейсам в TypeScript, можно определять и общие компоненты, чтобы использовать их повторно для разных типов данных. То же самое можно сделать с props и состояниями.
Затем компонент можно использовать либо с помощью вывода типа, либо напрямую указав типы данных.
Пример вывода типа:
Объявленные напрямую типы:
Обратите внимание: если в последнем примере список содержит строки вместо цифр, то TypeScript выдает ошибку во время процесса транспиляции.
Расширение HTML-элементов
Иногда компоненты функционируют и ведут себя как нативные HTML-элементы. Например, “border-box” (компонент, который отображает div с рамкой по умолчанию) или «big submit» (старая добрая кнопка отправки с размером по умолчанию и некоторым пользовательским поведением).
Для этих сценариев лучше всего определить тип компонента как нативный HTML-элемент или его расширение.
В коде выше я расширил HTML props по умолчанию и добавил новое: “title”.
Типы событий
Преимущество TypeScript в данном случае заключается в возможности использовать Generics (как в предыдущем примере), чтобы ограничить элементы, на которых может использоваться обработчик событий.
Например, следующий код не будет работать:
И вы получите подобное сообщение об ошибке:
Однако вы можете использовать объединения, чтобы разрешить повторное использование одного обработчика несколькими компонентами:
Интегрированное определение типа
В качестве последнего совета стоит упомянуть файлы index.d.ts и global.d.ts. Они устанавливаются при добавлении React в проект (если вы использовали npm, вы найдете их в папке npm_modules/@types).
Эти файлы содержат определения типов и интерфейсов, используемых React. Если вам нужно разобраться в props определенного типа, просто откройте эти файлы и просмотрите их содержимое.