логотип PurpleSchool
логотип PurpleSchool

Интеграция Typescript в React Native

Автор

Алексей Данилов

Введение

React Native позволяет создавать кроссплатформенные мобильные приложения с помощью JavaScript и React. Однако, по мере роста проекта и усложнения архитектуры, вам может стать трудно поддерживать масштабируемость и надежность кода на JavaScript. Здесь на помощь приходит TypeScript — строго типизированный язык, компилируемый в JavaScript, который позволяет ловить ошибки еще до запуска приложения.

Когда вы используете TypeScript вместе с React Native, вы получаете более мощную статическую проверку типов, улучшенное автодополнение и понятные контракты данных. Это критично, если вы работаете в команде или стремитесь к долгосрочной поддержке проекта.

В этой статье я покажу вам, как добавить и настроить TypeScript в существующем или новом проекте React Native, расскажу о типизации компонентов, props, state, hooks, а также дам советы по структуре проектов и ежедневной работе с типами.

Создание нового проекта React Native с TypeScript

Удобнее всего начинать с уже встроенной поддержки TypeScript в React Native CLI или Expo. Сейчас я покажу оба подхода.

С помощью React Native CLI

Вот типичная команда для создания проекта с поддержкой TypeScript:

npx react-native init MyTSApp --template react-native-template-typescript
  • С помощью этой команды создается проект с уже настроенными конфигами tsconfig.json и примерами компонентов на TypeScript.
  • Если у вас уже есть проект на JavaScript, добавьте необходимые пакеты и конфиги (расскажу об этом ниже).

Переход на TypeScript в React Native проекте может значительно улучшить качество кода, упростить отладку и повысить производительность. Однако, интеграция TypeScript требует внимательной настройки, понимания особенностей типов и умения работать с существующим JavaScript кодом. Чтобы успешно интегрировать TypeScript и использовать все его преимущества, нужно понимать, как настроить компилятор, как правильно типизировать компоненты и как интегрировать сторонние библиотеки. Если вы хотите детальнее погрузиться в интеграцию TypeScript в React Native и узнать о других аспектах разработки — приходите на наш большой курс React Native и Expo Router. На курсе 184 уроков и 11 упражнений, AI-тренажеры для безлимитной практики с кодом и задачами 24/7, решение задач с живым ревью наставника, еженедельные встречи с менторами.

С помощью Expo CLI

Expo CLI тоже умеет создавать проекты с TypeScript:

npx create-expo-app MyTSExpoApp -t expo-template-blank-typescript
  • Здесь Expo сразу положит вам tsconfig.json, а все файлы примеров будут в формате .ts или .tsx.

Добавление TypeScript в существующий проект

Если у вас уже есть React Native на JavaScript, последовательность шагов будет другой.

Установка зависимостей

Установите необходимые пакеты:

npm install --save-dev typescript @types/react @types/react-native
  • typescript — сам компилятор.
  • @types/react и @types/react-native — описания типов для React и React Native.

Добавление конфигурационного файла tsconfig.json

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

{
  "compilerOptions": {
    "target": "esnext", // Поддержка новых возможностей JS
    "module": "esnext",
    "jsx": "react",
    "strict": true, // Включает строгую проверку типов
    "moduleResolution": "node",
    "allowJs": true, // Разрешает работать с обычными файлами .js
    "skipLibCheck": true,
    "noEmit": true, // Не генерировать файлы, TypeScript только проверяет
    "esModuleInterop": true
  },
  "include": ["src", "App.tsx"],
  "exclude": ["node_modules"]
}
  • Этот конфиг подойдет для большинства случаев. Если ваши исходники не в каталоге src, замените его на актуальный.

Переименование файлов

Постепенно переименовывайте ваши .js / .jsx файлы в .ts / .tsx:

  • .ts — для обычных файлов TypeScript без JSX.
  • .tsx — для файлов с JSX-разметкой.

Типизация компонентов и props

Теперь, когда проект готов к работе с TypeScript, давайте разберемся, как типизировать различные элементы вашего приложения.

Функциональные компоненты

Вот базовый пример функционального компонента с типизированными props:

type ButtonProps = {
  title: string; // Ожидается строка
  onPress: () => void; // Колбек без параметров
};

const CustomButton: React.FC<ButtonProps> = ({ title, onPress }) => (
  <Button title={title} onPress={onPress} />
);

// Теперь на этапе написания кода TypeScript подскажет, если вы забудете передать title или onPress
  • Когда вы попытаетесь вызвать <CustomButton /> без обязательных параметров, редактор ругнется.
  • Добавлять необязательные параметры можно через вопросительный знак: color?: string.

Типизация state через useState

useState возвращает tuple. Вот пример, который поможет понять, как явно указать тип состояния:

const [count, setCount] = React.useState<number>(0);
// Здесь count всегда будет number, и TypeScript предупредит, если вы случайно попробуете присвоить туда строку

Если вы работаете с более сложными объектами:

type User = {
  id: number;
  name: string;
  email?: string;
};

const [user, setUser] = React.useState<User | null>(null);
// Теперь user строго либо User, либо null

Типизация ref

Использование useRef с типами:

const inputRef = React.useRef<TextInput>(null);
// inputRef.current имеет тип TextInput | null

Типизация классовых компонентов

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

type MyProps = { title: string };
type MyState = { isVisible: boolean };

class ExampleComponent extends React.Component<MyProps, MyState> {
  state = { isVisible: false };

  render() {
    return <Text>{this.props.title}</Text>;
  }
}
  • Здесь TypeScript контролирует и входные параметры и state компонента.

Использование сторонних библиотек и type definition’ы

В React Native часто используются сторонние библиотеки, которые могут не содержать типы "из коробки". В таком случае обратите внимание на @types:

  • Перед установкой новой библиотеки всегда проверяйте, есть ли для нее типы в репозитории DefinitelyTyped.
  • Например, для библиотеки lodash понадобится пакет @types/lodash.
npm install --save lodash
npm install --save-dev @types/lodash
  • Многие популярные библиотеки, вроде react-navigation или redux, поставляются с встроенными типами.

Пример интеграции стороннего пакета

Посмотрите, например, как выглядит импорт и использование типизированного пакета react-navigation:

import { NavigationContainer, NavigatorScreenParams } from '@react-navigation/native';
import { createStackNavigator, StackScreenProps } from '@react-navigation/stack';

type RootStackParamList = {
  Home: undefined;
  Details: { itemId: number };
};

const Stack = createStackNavigator<RootStackParamList>();

const HomeScreen: React.FC<StackScreenProps<RootStackParamList, 'Home'>> = ({ navigation }) => (
  <Button
    title="Open Details"
    // TypeScript проверит, что вы передаёте itemId
    onPress={() => navigation.navigate('Details', { itemId: 123 })}
  />
);
  • В этом примере строгое определение параметров экрана помогает избежать случайных ошибок при переходах.

Организация типов в проекте

Когда вы работаете над средним или крупным приложением, типов становится много. Лучше всего содержать их в отдельной папке или файле.

Пример структуры типа для пользователя

В директории src/types/User.ts:

export type UserProfile = {
  id: string;
  name: string;
  avatarUrl: string;
  birthDate?: string;
};

Затем используйте этот тип в компонентах:

import { UserProfile } from '../types/User';

const ProfileCard: React.FC<{ user: UserProfile }> = ({ user }) => (
  <View>
    <Text>{user.name}</Text>
    {/* Здесь TypeScript проверит все поля */}
  </View>
);
  • Такой подход улучшает переиспользуемость и облегчает рефакторинг.

Интеграция с линтерами и форматтерами

Важно не только писать типы, но и поддерживать единый стиль кода.

Настройка ESLint для TypeScript

Установите необходимые пакеты для поддержки TypeScript:

npm install --save-dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin

Дальше настройте ваш .eslintrc:

{
  "parser": "@typescript-eslint/parser",
  "plugins": ["@typescript-eslint"],
  "extends": [
    "plugin:@typescript-eslint/recommended",
    "plugin:react/recommended"
  ]
}

Настройка Prettier

Подключите Prettier, чтобы автоматически форматировать ваш код:

npm install --save-dev prettier eslint-config-prettier eslint-plugin-prettier

Создайте конфиг .prettierrc для глобальных правил форматирования.

Работа с типами в популярных паттернах React Native

Иногда встречаются ситуации, которые вызывают вопросы — как правильно типизировать их в TypeScript.

Типизация useContext

Когда вы используете контекст, типизация выглядит так:

type Theme = { color: string };

const ThemeContext = React.createContext<Theme | undefined>(undefined);

const App = () => (
  <ThemeContext.Provider value={{ color: 'blue' }}>
    <ThemedComponent />
  </ThemeContext.Provider>
);

const ThemedComponent = () => {
  const theme = React.useContext(ThemeContext);
  if (!theme) throw new Error('ThemeContext не найден');
  // theme гарантированно тип Theme
  return <View style={{ backgroundColor: theme.color }} />;
};

Типизация навигации

С навигацией в больших приложениях лучше выносить все возможные параметры экрана в единый тип RootStackParamList.

Типизация Redux-редьюсеров и экшенов

Вот пример типизации action и reducer:

type CounterAction = 
  | { type: 'increment' }
  | { type: 'decrement' };

function counterReducer(state: number, action: CounterAction): number {
  switch (action.type) {
    case 'increment':
      return state + 1;
    case 'decrement':
      return state - 1;
    default:
      return state;
  }
}

Общие советы по использованию TypeScript в React Native

  • Старайтесь описывать типы для props, состояний, параметров функций.
  • Используйте interface для описания props компонентов. Они лучше всего читаются при наследовании.
  • Чем раньше вы введете строгую типизацию, тем меньше будет проблем в будущем.
  • Не бойтесь постепенно переводить проект. Можно работать с файлами .js и .ts одновременно, если в tsconfig.json стоит allowJs: true.
  • Пользуйтесь автодополнением редактора (VSCode один из лучших).
  • Обязательно используйте строгий режим ("strict": true), чтобы избежать непредвиденных ошибок.

Заключение

Интеграция TypeScript в React Native заметно повышает качество и поддерживаемость мобильных приложений. Вы получаете строгую типизацию, информативные ошибки до запуска, качественный автокомплит и помощь редактора при рефакторинге. TypeScript особенно полезен на больших и долгоиграющих проектах — он снижает риск появления трудноуловимых ошибок и значительно ускоряет отладку.

Вы можете начать применение TypeScript на любом этапе разработки: с самого начала — с использованием шаблонов, или путем постепенного внедрения в уже существующий проект. Основное — быть последовательными и не пренебрегать типами там, где это действительно необходимо. Вы заметите, как качество и стабильность кода начнут расти уже после первых интеграций.

Интеграция TypeScript — важный шаг в развитии React Native проекта, но это только один из аспектов качественной разработки. Для создания надежных и масштабируемых приложений необходимо также уметь управлять состоянием, создавать переиспользуемые компоненты, использовать навигацию и работать с нативными модулями. На нашем курсе React Native и Expo Router вы найдете все необходимые знания и навыки. В первых 3 модулях уже доступно бесплатное содержание — начните погружаться в мир React Native прямо сегодня.

Частозадаваемые технические вопросы по теме и их решения

1. Как добавить поддержку абсолютных импортов с TypeScript в React Native?
— В tsconfig.json добавьте поле paths и baseUrl. Например: json { "compilerOptions": { "baseUrl": "src", "paths": { "@components/*": ["components/*"] } } } Еще потребуется настроить alias для babel: в babel.config.js добавьте babel-plugin-module-resolver.

2. Почему возникают ошибки “Type definition file not found” или не подтягиваются типы node_modules?
— Проверьте, что у вас указан параметр "skipLibCheck": true и не слишком ограничивающий "types" в tsconfig.json. Иногда помогает удалить node_modules и файл tsconfig.tsbuildinfo, затем выполнить npm install.

3. Как типизировать navigation props в экранах React Navigation v6?
— Используйте StackScreenProps<RootStackParamList, 'ScreenName'> для типизации параметров navigation и route. Это позволит TypeScript контролировать правильную передачу данных между экранами.

4. Как правильно использовать стороннюю библиотеку без доступных типов?
— Если типы отсутствуют на DefinitelyTyped, создайте файл типа declarations.d.ts и напишите: ts declare module 'имя-библиотеки'; Вы также можете создать собственные описания типов по мере необходимости.

5. Почему не работают автодополнения и проверки типов в .js файлах после добавления TypeScript?
— TypeScript, по умолчанию, не анализирует .js файлы. Нужно установить allowJs: true в tsconfig.json и добавить // @ts-check в начале js-файла, если нужна проверка типов. Для полноценной типизации лучше постепенно переводить такие файлы в .ts/.tsx.

Отображение webview в приложении на React NativeСтрелочка вправо

Постройте личный план изучения React-native до уровня Middle — бесплатно!

React-native — часть карты развития Mobile

  • step100+ шагов развития
  • lessons30 бесплатных лекций
  • lessons300 бонусных рублей на счет

Бесплатные лекции

Все гайды по React-native

Работа со ScrollView в React NativeРабота с видео в React NativeКак реализовать аудиоплеер на React NativeНастройка и использование input и textinput в React NativeИнтеграция видео плеера в приложение на React NativeИспользование выпадающих списков в React NativeСоздание и настройка native module на React NativeКак создать модальные окна в React NativeРабота с изображениями в React NativeОтображение списков данных в React NativeГайд по файловой системе в React NativeИнтеграция камеры в приложение на React NativeСоздание интерактивных кнопок в React Native
Как использовать векторные иконки в React Native5 популярных библиотек UI компонентов React NativeСоздание и использование tabs в React NativeРуководство по стилизации компонентов в React NativeОптимизация переходов между экранами в React NativeАдаптация safe area context на React NativeОбзор библиотек для навигации в React NativeСоздание сложных анимаций (reanimated) на React NativeИспользование библиотеки стилей Paper в React NativeРуководство по navigation в React NativeОптимизация отображения списков в React NativeКак реализовать linking на React NativeГайд по UI-китам для React NativeГде искать elements для приложения на React NativeРабота с цветами в React Native
Открыть базу знаний

Лучшие курсы по теме

изображение курса

React Native и Expo Router

Антон Ларичев
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Основы JavaScript

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее

Отправить комментарий