Использование TypeScript¶
TypeScript — это популярный способ добавления определений типов в кодовые базы JavaScript. Из коробки TypeScript поддерживает JSX, и вы можете получить полную поддержку React Web, добавив @types/react и @types/react-dom в ваш проект.
Вы узнаете
- TypeScript с компонентами React
- Примеры типизации с помощью хуков
- Общие типы из
@types/react - Дополнительные источники обучения
Установка¶
Все продуктовые React-фреймворки поддерживают использование TypeScript. Для установки следуйте руководству по конкретным фреймворкам:
Добавление TypeScript в существующий проект React¶
Чтобы установить последнюю версию определений типов React:
npm install @types/react @types/react-dom
В файле tsconfig.json необходимо установить следующие параметры компилятора:
domдолжен быть включен вlib(Примечание: Если опцияlibне указана,domбудет включен по умолчанию).-
Для параметра
jsxдолжна быть установлена одна из допустимых опций. Для большинства приложений достаточноpreserve.Если вы публикуете библиотеку, обратитесь к документации
jsx, чтобы узнать, какое значение выбрать.
TypeScript с компонентами React¶
Каждый файл, содержащий JSX, должен использовать расширение .tsx. Это специфическое для TypeScript расширение, которое сообщает TypeScript, что этот файл содержит JSX.
Написание TypeScript на React очень похоже на написание JavaScript на React. Ключевое отличие при работе с компонентом заключается в том, что вы можете предоставлять типы для реквизитов компонента. Эти типы можно использовать для проверки корректности и создания встроенной документации в редакторах.
Взяв компонент MyButton из руководства Быстрый старт, мы можем добавить тип, описывающий title для кнопки:
1 2 3 4 5 6 7 8 9 10 11 12 | |
Песочницы
Эти песочницы могут работать с кодом TypeScript, но в них не запускается программа проверки типов. Это означает, что вы можете использовать песочницы TypeScript для обучения, но не получите никаких ошибок или предупреждений о типах. Чтобы получить проверку типов, вы можете использовать TypeScript Playground или воспользоваться более полнофункциональной онлайн-песочницей.
Этот встроенный синтаксис - самый простой способ предоставить типы для компонента, но когда у вас появляется несколько полей для описания, он может стать громоздким. Вместо этого вы можете использовать interface или type для описания свойств компонента:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | |
Тип, описывающий свойства вашего компонента, может быть простым или сложным, как вам нужно, но они должны быть объектным типом, описанным с помощью type или interface. Вы можете узнать о том, как TypeScript описывает объекты в Object Types, но вам также может быть интересно использовать Union Types для описания свойства, которое может быть одним из нескольких различных типов, и руководство Creating Types from Types для более сложных случаев использования.
Примеры хуков¶
Определения типов из @types/react включают типы для встроенных хуков, так что вы можете использовать их в своих компонентах без дополнительных настроек. Они созданы с учетом кода, который вы пишете в своем компоненте, поэтому вы будете получать выведенные типы большую часть времени, и в идеале вам не нужно будет заниматься тонкостями создания типов.
Тем не менее, мы можем рассмотреть несколько примеров того, как задавать типы для хуков.
useState¶
Хук useState повторно использует значение, переданное в качестве начального состояния, чтобы определить, каким должен быть тип этого значения. Например:
1 2 | |
присвоит enabled тип boolean, а setEnabled будет функцией, принимающей либо аргумент boolean, либо функцию, возвращающую boolean. Если вы хотите явно указать тип состояния, вы можете сделать это, указав тип аргумента в вызове useState:
1 2 | |
В данном случае это не очень полезно, но часто тип может потребоваться, если у вас есть тип объединения. Например, status здесь может быть одной из нескольких различных строк:
1 2 3 | |
Или, как рекомендуется в Принципах структурирования состояния, вы можете сгруппировать связанные состояния как объект и описать различные возможности с помощью типов объектов:
1 2 3 4 5 6 7 8 9 | |
useReducer¶
Хук useReducer - это более сложный хук, который принимает функцию редуктора и начальное состояние. Типы для функции редуктора выводятся из начального состояния. Вы можете указать тип в аргументе в вызове useReducer, чтобы задать тип для состояния, но часто лучше установить тип в начальном состоянии:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | |
Мы используем TypeScript в нескольких ключевых местах:
interface Stateописывает форму состояния редуктора.type CounterActionописывает различные действия, которые могут быть отправлены редуктору.const initialState: Stateпредоставляет тип для начального состояния, а также тип, который используетсяuseReducerпо умолчанию.stateReducer(state: State, action: CounterAction): Stateустанавливает типы для аргументов и возвращаемого значения функции reducer.
Более явной альтернативой установке типа в initialState является предоставление аргумента типа в useReducer:
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
useContext¶
Хук useContext - это техника передачи данных по дереву компонентов без необходимости передавать реквизиты через компоненты. Она используется при создании компонента-провайдера и часто при создании хука для потребления значения в дочернем компоненте.
Тип значения, предоставляемого контекстом, выводится из значения, переданного в вызове createContext:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | |
Эта техника работает, когда у вас есть значение по умолчанию, которое имеет смысл - но иногда бывают случаи, когда это не так, и в этих случаях null может показаться разумным значением по умолчанию. Однако, чтобы система типов могла понять ваш код, вам нужно явно установить ContextShape | null в createContext.
Это приводит к тому, что вам нужно исключить | null в типе для потребителей контекста. Мы рекомендуем, чтобы хук выполнял проверку на существование этого типа во время выполнения и выбрасывал ошибку при его отсутствии:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | |
useMemo¶
Хуки useMemo создают/восстанавливают доступ к запомненному значению из вызова функции, перезапуская функцию только при изменении зависимостей, переданных в качестве второго параметра. Результат вызова хука определяется по возвращаемому значению функции в первом параметре. Вы можете быть более явными, указав аргумент типа в Hook.
1 2 3 4 5 6 | |
useCallback¶
useCallback обеспечивают стабильную ссылку на функцию, пока зависимости, переданные во втором параметре, одинаковы. Как и в useMemo, тип функции определяется по возвращаемому значению функции в первом параметре, но вы можете быть более явными, указав аргумент типа в Hook.
1 2 3 | |
При работе в строгом режиме TypeScript useCallback требует добавления типов для параметров обратного вызова. Это связано с тем, что тип обратного вызова выводится из возвращаемого значения функции, а без параметров тип не может быть полностью понят.
В зависимости от ваших предпочтений в стиле кода, вы можете использовать функции *EventHandler из типов React, чтобы задать тип обработчика события одновременно с определением обратного вызова:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
Полезные типы¶
Существует довольно обширный набор типов из пакета @types/react, его стоит прочитать, когда вы почувствуете, как взаимодействуют React и TypeScript. Вы можете найти их в папке React в DefinitelyTyped. Здесь мы рассмотрим несколько наиболее распространенных типов.
События DOM¶
При работе с событиями DOM в React тип события часто можно определить из обработчика события. Однако, если вы хотите извлечь функцию, которая будет передана обработчику события, вам нужно будет явно задать тип события.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
В типах React предусмотрено множество типов событий - полный список можно найти здесь, который основан на наиболее популярных событиях из DOM.
При определении нужного типа вы можете сначала посмотреть на hover-информацию для используемого обработчика события, которая покажет тип события.
Если вам нужно использовать событие, которое не включено в этот список, вы можете использовать тип React.SyntheticEvent, который является базовым типом для всех событий.
Children¶
Существует два общих способа описания дочерних элементов компонента. Первый - использовать тип React.ReactNode, который представляет собой объединение всех возможных типов, которые могут быть переданы в качестве дочерних в JSX:
1 2 3 4 | |
Это очень широкое определение детей. Второе - использовать тип React.ReactElement, который относится только к элементам JSX, а не к примитивам JavaScript вроде строк или чисел:
1 2 3 4 | |
Обратите внимание, что вы не можете использовать TypeScript для описания того, что дочерние элементы являются определенным типом JSX-элементов, поэтому вы не можете использовать систему типов для описания компонента, который принимает только <li> дочерние элементы.
Вы можете увидеть все примеры как React.ReactNode, так и React.ReactElement с проверкой типов в этой площадке TypeScript.
Свойства стиля¶
При использовании встроенных стилей в React вы можете использовать React.CSSProperties для описания объекта, передаваемого в реквизит style. Этот тип представляет собой объединение всех возможных CSS-свойств и является хорошим способом убедиться, что вы передаете действительные CSS-свойства в реквизит style, а также получить автозаполнение в вашем редакторе.
1 2 3 | |
Дальнейшее обучение¶
В этом руководстве мы рассмотрели основы использования TypeScript с React, но вам предстоит узнать еще много нового. Отдельные страницы API в документации могут содержать более подробную документацию о том, как использовать их с TypeScript.
Мы рекомендуем следующие ресурсы:
-
The TypeScript handbook - официальная документация по TypeScript, охватывающая большинство ключевых возможностей языка.
-
The TypeScript release notes подробно рассказывает о каждой новой функции.
-
React TypeScript Cheatsheet - это поддерживаемая сообществом шпаргалка по использованию TypeScript с React, охватывающая множество полезных крайних случаев и предоставляющая более широкую информацию, чем этот документ.
-
TypeScript Community Discord - отличное место, где можно задать вопросы и получить помощь по проблемам TypeScript и React.
Источник — https://react.dev/learn/typescript