$ sudo teach IT

Модуль 11: React + TypeScript

Урок 11.1: Настройка React-проекта с TypeScript

Продвинутый уровень 60 минут

1. Введение в React с TypeScript

Добро пожаловать в Модуль 11! Сегодня мы начнём изучение одной из самых мощных комбинаций в современной фронтенд-разработке — React с TypeScript. Эта связка используется в ведущих технологических компаниях по всему миру и становится стандартом индустрии.

React — это библиотека для построения пользовательских интерфейсов, созданная компанией Facebook (теперь Meta). TypeScript — это строго типизированный язык программирования, разработанный Microsoft. Когда вы объединяете эти две технологии, вы получаете среду разработки, которая сочетает в себе гибкость React и надёжность TypeScript.

В этом уроке мы подробно разберём, как создать новый React-проект с поддержкой TypeScript, какие инструменты для этого используются, и как настроить среду разработки для максимально продуктивной работы.

Почему React + TypeScript?

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

  • Безопасность типов — TypeScript помогает обнаруживать ошибки на этапе компиляции, ещё до запуска приложения. Это особенно важно в больших проектах с множеством компонентов.
  • Автодополнение в IDE — Когда вы работаете с типизированными пропсами и состоянием, ваш редактор кода может точно предсказать, какие значения доступны, какие методы можно вызвать, и какие типы данных ожидаются.
  • Самодокументируемый код — Типы функциют как документация. Любой разработчик, открыв ваш компонент, сразу видит, какие данные он ожидает и что возвращает.
  • Упрощённый рефакторинг — При изменении интерфейсов TypeScript мгновенно указывает на все места, которые нужно обновить.
  • Лучшая поддержкакрупных проектов — В командной разработке TypeScript обеспечивает единый контракт между компонентами.

Требования к среде разработки

Перед началом работы убедитесь, что у вас установлены следующие инструменты:

Node.js версии 16.0 или выше (рекомендуется последняя LTS-версия). Проверить установку можно командой: node --version

npm (входит в комплект с Node.js) или yarn — менеджер пакетов для установки зависимостей. Проверить: npm --version

Кодовый редактор — Visual Studio Code с расширениями: ESLint, Prettier, TypeScript Nightly (опционально), и расширением для React (ES7+ React/Redux/React-Native snippets).

2. Создание проекта с помощью Create React App

Самый простой способ создать React-проект с TypeScript — использовать официальный инструмент Create React App с шаблоном TypeScript. Давайте разберём процесс пошагово.

Шаг 1: Установка Create React App

Если у вас ещё не установлен Create React App глобально, выполните команду:

# Установка Create React App глобально
npm install -g create-react-app

Однако вы можете не устанавливать его глобально, а использовать через npx:

# Использование через npx (рекомендуется)
npx create-react-app my-typescript-app --template typescript

Эта команда создаст новую директорию my-typescript-app с полной структурой React-проекта, настроенного для работы с TypeScript.

Шаг 2: Разбор структуры проекта

После создания проекта давайте изучим его структуру:

my-typescript-app/
├── node_modules/
├── public/
│   ├── favicon.ico
│   ├── index.html
│   ├── logo192.png
│   ├── logo512.png
│   ├── manifest.json
│   └── robots.txt
├── src/
│   ├── App.css
│   ├── App.test.tsx
│   ├── App.tsx
│   ├── index.css
│   ├── index.tsx
│   ├── logo.svg
│   ├── react-app-env.d.ts
│   └── reportWebVitals.ts
│   └── setupTests.ts
├── tsconfig.json
├── tsconfig.node.json
├── package.json
├── package-lock.json
└── README.md

Обратите внимание на несколько ключевых файлов, которые отличают TypeScript-проект от обычного JavaScript-проекта:

tsconfig.json — файл конфигурации TypeScript, определяющий параметры компиляции

tsconfig.node.json — дополнительная конфигурация для Node.js-среды

*.tsx и *.ts файлы — файлы с расширениями TypeScript

Шаг 3: Запуск проекта

Для запуска проекта выполните следующие команды:

# Переход в директорию проекта
cd my-typescript-app

# Запуск development-сервера
npm start

Приложение автоматически откроется в браузере по адресу http://localhost:3000. Вы увидите стандартную страницу React с логотипом и приветственным сообщением.

3. Конфигурация TypeScript (tsconfig.json)

Файл tsconfig.json — это сердце конфигурации TypeScript. Давайте подробно разберём каждый параметр, чтобы вы понимали, за что отвечает каждая настройка.

Базовая конфигурация

По умолчанию Create React App создаёт следующую конфигурацию:

{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx"
  },
  "include": ["src"]
}

Разбор параметров

Давайте разберём каждый важный параметр:

"target": "es5"

Определяет версию JavaScript, в которую будет компилироваться TypeScript. ES5 совместим со всеми современными браузерами. Вы можете изменить на "es6" или "es2020", если не поддержка старых браузеров не требуется.

"lib": ["dom", "dom.iterable", "esnext"]

Указывает, какие типы доступны из стандартных библиотек. "dom" предоставляет типы для работы с DOM, "dom.iterable" — для итераторов по DOM-элементам, "esnext" — для новых возможностей JavaScript.

"strict": true

Включает все строгие проверки типов. Это включает: strictNullChecks, strictFunctionTypes, strictBindCallApply, strictPropertyInitialization, noImplicitAny, noImplicitThis, alwaysStrict. Рекомендуется всегда держать это значение включённым.

"jsx": "react-jsx"

Определяет, как TypeScript обрабатывает JSX-выражения. "react-jsx" использует новый автоматический импорт React (не нужно писать import React в каждом файле).

"esModuleInterop": true

Позволяет импортировать модули CommonJS (module.exports) с помощью синтаксиса import/export. Это делает код более совместимым с различными библиотеками.

"noFallthroughCasesInSwitch": true

Запрещает пропуск break в switch-выражениях. Это помогает избежать распространённой ошибки, когда разработчик забывает поставить break ивыполнениепродолжаетвыполнениеследующий case.

4. Альтернативный способ: Vite + React + TypeScript

Помимо Create React App, существует более современный и быстрый инструмент для создания проектов — Vite. Vite использует native ES-модули и работает значительно быстрее, чем Webpack (который используется в Create React App).

Создание проекта с Vite

# Создание нового проекта с Vite
npm create vite@latest my-vite-app -- --template react-ts

При выполнении этой команды Vite предложит выбрать шаблон. Выберите "React + TypeScript" из списка доступных вариантов.

Структура проекта Vite

my-vite-app/
├── node_modules/
├── public/
│   └── vite.svg
├── src/
│   ├── assets/
│   │   └── react.svg
│   ├── App.css
│   ├── App.tsx
│   ├── index.css
│   ├── main.tsx
│   └── vite-env.d.ts
├── index.html
├── package.json
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts

Обратите внимание на ключевые отличия от Create React App:

  • index.html находится в корне проекта, а не в папке public
  • vite.config.ts — файл конфигурации Vite (вместо.config.js)
  • main.tsx — точка входа (вместо index.tsx)
  • Более простая и минималистичная структура

Конфигурация Vite

Файл vite.config.ts выглядит следующим образом:

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [react()],
  server: {
    port: 3000,
    open: true,
  },
})

5. Первый типизированный компонент

Теперь, когда проект создан и настроен, давайте напишем наш первый типизированный React-компонент. Мы начнём с простого примера и постепенно усложним.

Структура типизированного компонента

Создайте файл src/components/Greeting.tsx:

import React from 'react';

// Определяем интерфейс для пропсов компонента
interface GreetingProps { name: string; age?: number; // Необязательный пропс
greeting?: string; } // Функциональный компонент с типизацией пропсов
const Greeting: React.FC<GreetingProps> = ({ name, age, greeting }) => { const displayGreeting = greeting || 'Привет'; const ageText = age ? `, тебе ${age} лет` : ''; return ( <div className="greeting"> <h2>{displayGreeting}, {name}!{ageText}</h2> </div> ); }; export default Greeting;

Использование этого компонента в App.tsx:

import React from 'react';
import Greeting from './components/Greeting';

function App() {
  return (
    <div className="App">
      {/*. Типизация автоматически проверяет пропсы */}
<Greeting name="Анна" age={25} greeting="Добро пожаловать" /> {/*. Ошибка компиляции: name обязателен */}
{/* <Greeting age={25} /> */}
{/*. Ошибка компиляции: age должен быть числом */}
{/* <Greeting name="Анна" age="двадцать пять" /> */}
</div> ); } export default App;

Дополнительные типы для React

TypeScript предоставляет множество встроенных типов для React. Вот некоторые из самых используемых:

React.FC<P> — тип для функционального компонента с пропсами типа P

React.ReactNode — тип для любого валидного JSX-узла (строки, числа, элементы, массивы, фрагменты, null, undefined)

React.CSSProperties — тип для CSS-стилей в формате объекта

React.ChangeEvent<HTMLInputElement> — тип для события изменения input-элемента

React.FormEvent<HTMLFormElement> — тип для события отправки формы

6. Настройка ESLint и Prettier

Для поддержания чистоты и единообразия кода необходимо настроить линтер (ESLint) и форматтер (Prettier). Эти инструменты помогут автоматически обнаруживать ошибки и форматировать код.

Установка и настройка ESLint

# Установка ESLint и необходимых плагинов
npm install -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-react eslint-plugin-react-hooks

Создайте файл .eslintrc.json в корне проекта:

{
  "root": true,
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaVersion": 2020,
    "sourceType": "module",
    "ecmaFeatures": {
      "jsx": true
    }
  },
  "plugins": ["@typescript-eslint", "react", "react-hooks"],
  "extends": [
    "eslint:recommended",
    "plugin:@typescript-eslint/recommended",
    "plugin:react/recommended",
    "plugin:react-hooks/recommended"
  ],
  "settings": {
    "react": {
      "version": "detect"
    }
  },
  "rules": {
    "react/react-in-jsx-scope": "off",
    "@typescript-eslint/explicit-module-boundary-types": "off",
    "@typescript-eslint/no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }]
  }
}

Установка и настройка Prettier

# Установка Prettier и плагина для конфликтов с ESLint
npm install -D prettier eslint-config-prettier eslint-plugin-prettier

Создайте файл .prettierrc:

{
  "semi": true,
  "trailingComma": "es5",
  "singleQuote": true,
  "printWidth": 100,
  "tabWidth": 2,
  "useTabs": false,
  "bracketSpacing": true,
  "jsxBracketSameLine": false,
  "arrowParens": "always"
}

Настройка VS Code

Добавьте в .vscode/settings.json:

{
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  },
  "typescript.preferences.importModuleSpecifier": "relative",
  "typescript.suggest.autoImports": true
}

7. Структура проекта и архитектура

Правильная структура проекта — залог его масштабируемости и поддерживаемости. Давайте рассмотрим рекомендуемую структуру для React-проекта с TypeScript.

Рекомендуемая структура папок

src/
├── components/          # Переиспользуемые компоненты
│   ├── common/         # Общие компоненты (Button, Input, Modal)
│   ├── layout/         # Компоненты макета (Header, Footer, Sidebar)
│   └── features/       # Компоненты функциональных областей
├── hooks/              # Пользовательские хуки
├── services/           # Сервисы (API, аутентификация, логирование)
├── types/              # TypeScript-интерфейсы и типы
├── utils/              # Вспомогательные функции
├── constants/          # Константы приложения
├── context/            # React Context
├── assets/             # Статические ресурсы (изображения, шрифты)
├── styles/             # Глобальные стили
├── pages/              # Страницы (компоненты маршрутов)
├── App.tsx             # Корневой компонент
├── index.tsx           # Точка входа
└── react-app-env.d.ts  # Объявления типов

Файл типов (types/index.ts)

Создайте централизованный файл для хранения всех типов приложения:

// src/types/index.ts

// Типы для пользователя
export interface User { id: string; name: string; email: string; avatar?: string; role: 'admin' | 'user' | 'guest'; createdAt: Date; } // Типы для поста
export interface Post { id: string; title: string; content: string; author: User; tags: string[]; published: boolean; createdAt: Date; updatedAt: Date; } // Типы для API-ответов
export interface ApiResponse<T> { data: T; status: number; message?: string; } // Типы для пагинации
export interface PaginatedResponse<T> extends ApiResponse<T> { total: number; page: number; limit: number; totalPages: number; } // Типы для событий
export type FormInputEvent = React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>; export type FormSelectEvent = React.ChangeEvent<HTMLSelectElement>; export type FormSubmitEvent = React.FormEvent<HTMLFormElement>;

Бесполезные ошибки TypeScript в React

Одна из самых распространённых ошибок при работе с React и TypeScript — это типизация обработчиков событий. Вот как это правильно делать:

// Неправильно:
const handleChange = (e) => { console.log(e.target.value); // e имеет тип 'any'
}; // Правильно:
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => { console.log(e.target.value); // e.target.value имеет тип string
}; // Ещё лучше — вынести тип в отдельную переменную:
type InputChangeEvent = React.ChangeEvent<HTMLInputElement>; const handleChange = (e: InputChangeEvent) => { console.log(e.target.value); };

8. Практическое задание

Теперь давайте применим полученные знания на практике. Выполните следующие задания:

Задание 1: Создание проекта

  1. Создайте новый React-проект с TypeScript используя Create React App или Vite
  2. Настройте ESLint и Prettier
  3. Создайте структуру папок, описанную в уроке
  4. Определите базовые типы в файле types/index.ts

Задание 2: Компонент профиля

  1. Создайте интерфейс UserProfile с полями: name, email, avatar (опционально), bio (опционально)
  2. Создайте компонент UserProfile, который принимает эти пропсы
  3. Добавьте обработку случая, когда avatar не передан (показать заглушку)
  4. Создайте компонент UserList, который принимает массив пользователей и отображает список

Задание 3: Стилизация

  1. Создайте интерфейс ButtonProps с полями: variant ('primary' | 'secondary' | 'danger'), size ('small' | 'medium' | 'large'), disabled (boolean), children (React.ReactNode)
  2. Создайте компонент Button с правильной типизацией
  3. Примените стили в зависимости от пропсов variant и size
  4. Проверьте, что TypeScript не позволяет передать неверные значения

9. Полезные команды

Для работы с проектом вам понадобятся следующие команды:

Запуск development-сервера:

npm start

Сборка для продакшена:

npm run build

Запуск тестов:

npm test

Проверка типов без компиляции:

npx tsc --noEmit

Форматирование всех файлов:

npx prettier --write "src/**/*.{ts,tsx,css}"

Запуск линтера с исправлением:

npx eslint src --fix

10. Итоги урока

В этом уроке мы подробно изучили:

  • Преимущества использования React с TypeScript
  • Создание проекта с помощью Create React App и Vite
  • Настройку tsconfig.json и его параметры
  • Настройку ESLint и Prettier для поддержания чистоты кода
  • Рекомендуемую структуру проекта
  • Создание первого типизированного компонента
  • Полезные команды для работы с проектом

Советы для эффективной работы

  1. Всегда используйте строгий режим TypeScript (strict: true)
  2. Определяйте интерфейсы для пропсов в том же файле, что и компонент, или в централизованном файле типов
  3. Используйте автоматическое форматирование при сохранении файла
  4. Не бойтесь использовать встроенные типы React
  5. Регулярно запускайте проверку типов (tsc --noEmit)

В следующем уроке мы подробно разберём типизацию пропсов компонентов — один из самых важных аспектов работы с React и TypeScript.

Отличная работа! Вы успешно изучили настройку React-проекта с TypeScript!

Тест по настройке React-проекта с TypeScript

1 вопрос

Тест по конфигурации TypeScript

1 вопрос

Тест по Vite и React

1 вопрос

Настройка tsconfig для React

Premium