How to use typescript with react

Adding TypeScript

Note: this feature is available with react-scripts@2.1.0 and higher.

TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.

Installation​

To start a new Create React App project with TypeScript, you can run:

npx create-react-app my-app --template typescript 
yarn create react-app my-app --template typescript 

If you’ve previously installed create-react-app globally via npm install -g create-react-app , we recommend you uninstall the package using npm uninstall -g create-react-app or yarn global remove create-react-app to ensure that npx always uses the latest version.

Global installs of create-react-app are no longer supported.

To add TypeScript to an existing Create React App project, first install it:

npm install --save typescript @types/node @types/react @types/react-dom @types/jest 
yarn add typescript @types/node @types/react @types/react-dom @types/jest 

Next, rename any file to be a TypeScript file (e.g. src/index.js to src/index.tsx ) and restart your development server!

Type errors will show up in the same console as the build one. You’ll have to fix these type errors before you continue development or build your project. For advanced configuration, see here.

Getting Started with TypeScript and React​

You are not required to make a tsconfig.json file, one will be made for you. You are allowed to edit the generated TypeScript configuration.

Troubleshooting​

If your project is not created with TypeScript enabled, npx may be using a cached version of create-react-app . Remove previously installed versions with npm uninstall -g create-react-app or yarn global remove create-react-app (see #6119).

If you are currently using create-react-app-typescript, see this blog post for instructions on how to migrate to Create React App.

Constant enums and namespaces are not supported, you can learn about the constraints of using Babel with TypeScript here.

Источник

Использование Typescript с React – руководство для новичков

Друзья, в преддверии выходных хотим поделиться с вами еще одной интересной публикацией, которую хотим приурочить к запуску новой группы по курсу «Разработчик JavaScript».

Потратив последние несколько месяцев на разработку приложений на React и библиотек с использованием Typescript, я решил поделиться некоторыми вещами, которые узнал за это время. В этом руководстве я расскажу вам про шаблоны, которые я использую для Typescript и React в 80% случаев.

Стоит ли изучать Typescript для разработки приложений на React? Стоит, еще как стоит! Для себя я осознал на практике, что строгая типизация приводит к написанию гораздо более надежного кода, быстрой разработке, особенно в крупных проектах. Сначала вы, вероятно, будете разочарованы, но по мере работы вы обнаружите, что хотя бы минимальный шаблон действительно будет очень кстати.

И если вы застряли на чем-то, помните, что вы всегда можете типизировать что- нибудь как any. Any – ваш новый друг. А теперь перейдем непосредственно к примерам.

Ваш базовый компонент react с typescript

Как же выглядит стандартный компонент react на typescript? Давайте сравним его с компонентом react в javascript.

import React from 'react' import PropTypes from 'prop-types' export function StandardComponent(< children, title = 'Dr.' >) < return ( : ) > StandardComponent.propTypes =

А теперь версия на typescript:

import * as React from 'react' export interface StandardComponentProps < title?: string children: React.ReactNode >export function StandardComponent(< children, title = 'Dr.', >: StandardComponentProps) < return ( : ) >

Очень похоже, не так ли? Мы заменили propTypes на интерфейс typescript .

Заголовок prop остается необязательным, в то время как все еще требуется prop наследника. Мы экспортировали наш интерфейс на случай, если другому компоненту понадобится на него ссылка.

Расширение стандартных атрибутов HTML

Если мы хотим, чтобы родительский компонент мог обеспечивать дополнительные типизированные атрибуты div , такие как aria-hidden , style или className , мы можем определить их в interface или же расширить встроенный интерфейс. В приведенном ниже примере, мы говорим, что наш компонент принимает любые стандартные свойства div в дополнение к заголовку и наследникам.

import * as React from 'react' export interface SpreadingExampleProps extends React.HTMLAttributes  < title?: string children: React.ReactNode >export function SpreadingExample(< children, title = 'Dr.', . other >: SpreadingExampleProps) < return ( > : ) > 

Обработка событий

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

export interface EventHandlerProps < onClick: (e: React.MouseEvent) =>void > export function EventHandler(< onClick >: EventHandlerProps) < // handle focus events in a separate function function onFocus(e: React.FocusEvent) < console.log('Focused!', e.currentTarget) >return (  ) >

Не знаете, какую сигнатуру аргумента использовать? В редакторе наведите курсором на соответствующее свойство обработчика событий.

Использование дженериков с компонентами react

Это более продвинутая функция, но она действительно мощная. Как правило, вы определяете типы данных в компонентах react конкретными атрибутами. Предположим, вашему компоненту требуется объект profile .

interface ProfileType < name: string image: string age: number | null >interface ProfilesProps < profiles: Array> function Profiles(props: ProfilesProps) < // render a set of profiles >

А теперь давайте представим, что у вас есть компонент, который может принимать массив любого типа. Дженерики похожи на отправку посылки по почте. Курьер (наш компонент) не должен знать содержимое посылки, которую вы отправляете, но отправитель (родительский компонент) ожидает, что получатель получит содержимое, которое он отправил.

interface GenericsExampleProps  < children: (item: T) =>React.ReactNode items: Array > export function GenericsExample(< items, children, >: GenericsExampleProps) < return ( 
< return children(item) >)>
) >

Немного странный пример… тем не менее он демонстрирует суть. Компонент принимает массив элементов любого типа, проходит по нему и вызывает функцию children как рендер функцию с элементом массива. Когда наш родительский компонент предоставляет колбэк рендера как наследника, элемент будет типизирован правильно!

Не поняли? Это нормально. Я сам еще не разобрался с дженериками до конца, но вам вряд ли понадобится понимать их досконально. Однако, чем больше вы будете работать с typescript , тем больше в этом будет смысла.

Типизация хуков (hooks)

Хуки в основном работают из коробки. Двумя исключениями могут быть только useRef и useReducer . Пример ниже показывает, как мы можем типизировать ссылки (refs).

import * as React from 'react' interface HooksExampleProps <> export function HooksExample(props: HooksExampleProps) < const [count, setCount] = React.useState(0) const ref = React.useRef(null) // start our timer React.useEffect( () => < const timer = setInterval(() =>< setCount(count + 1) >, 1000) return () => clearTimeout(timer) >, [count] ) // measure our element React.useEffect( () => < if (ref.current) < console.log(ref.current.getBoundingClientRect()) >>, [ref] ) return >Count: > 

Наше состояние автоматически типизируется, но мы вручную типизировали ref, чтобы показать, что он будет иметь значение null или содержать элемент div . Когда мы обращаемся к ref в функции useEffect , нам нужно убедиться, что он не равен null .

Типизация редуктора

С редуктором немного сложнее, но если он правильно типизирован, то это замечательно.

// Yeah, I don't understand this either. But it gives us nice typing // for our reducer actions. type Action = V extends void ? < type: K >: < type: K >& V // our search response type interface Response < id: number title: string >// reducer actions. These are what you'll "dispatch" export type ActionType = | Action> | Action >> // the form that our reducer state takes interface StateType < searchResponse: Arrayquery: string > // our default state const initialState: StateType = < searchResponse: [], query: '', >// the actual reducer function reducer(state: StateType, action: ActionType) < switch (action.type) < case 'QUERY': return < . state, query: action.value, >case 'SEARCH': return < . state, searchResponse: action.value, >> > interface ReducerExampleProps < query: string >export function ReducerExample(< query >: ReducerExampleProps) < const [state, dispatch] = React.useReducer(reducer, initialState) React.useEffect( () => < if (query) < // emulate async query setTimeout(() =>< dispatch(< type: 'SEARCH', value: [< id: 1, title: 'Hello world' >], >) >, 1000) > >, [query] ) return state.searchResponse.map(response => ( > )) >

Использование typeof и keyof чтобы типизировать варианты компонента

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

Наш компонент кнопки должен принимать свойство type , которое может быть
любым ключом из объекта styles (например, «primary» или «danger»). Мы можем типизировать его достаточно просто:

const styles = < primary: < color: 'blue', >, danger: < color: 'red', >, > // creates a reusable type from the styles object type StylesType = typeof styles // ButtonType = any key in styles export type ButtonType = keyof StylesType interface ButtonProps < type: ButtonType >export function Button(< type = 'primary' >: ButtonProps) < return  >

Эти примеры помогут вам пройти 80% пути. Если вы застряли, то очень часто стоит
просто взглянуть на существующие примеры с открытым исходным кодом.

Sancho UI — это набор компонентов react,
построенный с помощью typescript и emotion.
Blueprint — это еще один набор компонентов
react , построенный на typescript .

Ну и по устоявшейся традиции ждем ваши комментарии.

Источник

How to Use TypeScript with React Components

Post cover

In this post, I’m going to discuss why and how to use TypeScript to type React components.

You’ll find how to annotate component props, mark a prop optional, and indicate the return type.

Before I go on, let me recommend something to you.

The path to becoming proficient in React isn’t easy. but fortunately with a good teacher you can shortcut.

Take the course «React Front To Back Course» by Brad Traversy to improve your React skills in a fun and practical way. Use the coupon code DMITRI and get your 20% discount!

Table of Contents

1. Why typing React components?

TypeScript is useful if you’re coding middle and bigger size web applications. Annotating variables, objects, and functions creates contracts between different parts of your application.

For example, let’s say I am the author of a component that displays a formatted date on the screen.

According to the FormatDateProps interface, the component FormatDate the value of date prop can only be an instance of Date . That is a constraint.

Why is this constraint important? Because the FormatDate component calls the method date.toLocaleString() on the date instance, and the date prop have to be a date instance. Otherwise, the component wouldn’t work.

Then the user of the FormatDate component would have to satisfy the constraint, and provide date prop only with Date instances:

If the user forgets about the constraint, and for example provides a string «Sep 28 2021» to date prop:

then TypeScript will show a type error.

That’s great because the error is caught during development, without hiding in the codebase.

In my opinion, the best benefit React takes from TypeScript is the props typing.

Typing a React component is usually a 2 steps process.

A) Define the interface that describes what props the component accepts using an object type. A good naming convention for the props interface is ComponentName + Props = ComponentNameProps

B) Then use the interface to annotate the props parameter inside the functional component function.

For example, let’s annotate a component Message that accepts 2 props: text (a string) and important (a boolean):

Источник

Читайте также:  Самый сложный код python
Оцените статью