TypeScript Миграция

Миграция с JavaScript на TypeScript способна существенно улучшить сопровождение кодовой базы и удобство работы разработчиков.

Это руководство проведёт вас через весь процесс — шаг за шагом.


Подготовительный этап

Оцените свою кодовую базу

Перед началом миграции:

  • определите размер и сложность кодовой базы;
  • задокументируйте процесс сборки и зависимости;
  • проверьте наличие существующих определений типов (файлов .d.ts);
  • выделите критически важные участки, требующие особого внимания.

Настройте систему контроля версий

Убедитесь, что у вас есть чистый репозиторий Git (или аналог):


# Создайте новую ветку для миграции
git checkout -b typescript-migration

# Зафиксируйте текущее состояние
git add .
git commit -m "Состояние перед миграцией на TypeScript"


Настройка окружения

Установите TypeScript


# Установите TypeScript как зависимость для разработки
npm install --save-dev typescript @types/node

Создайте tsconfig.json

Начните с базового файла конфигурации tsconfig.json:


{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "outDir": "./dist",
    "rootDir": "./src"
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}

Примечание: скорректируйте параметр target в соответствии с минимально поддерживаемыми окружениями.


Подходы к миграции

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

Переносите по одному файлу, оставляя остальные в формате JavaScript.


{
  "compilerOptions": {
    "allowJs": true,
    "checkJs": true
  }
}

Оптимально для крупных кодовых баз, когда важно минимизировать сбои в работе.

Миграция "всё сразу"

Переименуйте все .js-файлы в .ts и исправьте возникающие ошибки.


# Переименуйте все JS‑файлы в TS
find src -name "*.js" -exec sh -c 'mv "$0" "${0%.js}.ts"' {} \;

Оптимально для небольших и средних проектов, а также новых проектов.

Важное замечание: Для крупных проектов настоятельно рекомендуется постепенный подход — так вы снизите риски сбоев и сделаете процесс более управляемым.

Миграция пошагово

Начните с настроек

Создайте базовый tsconfig.json с рекомендуемыми параметрами:


{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "outDir": "./dist",
    "rootDir": "./src",
    "allowJs": true,
    "checkJs": true,
    "noEmit": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

Включите проверку типов для JavaScript

Добавьте // @ts-check в начало JavaScript‑файлов, чтобы активировать проверку типов:


// @ts-check

/** @type {string} */
const name = 'John';

// TypeScript обнаружит эту ошибку
name = 42; // Ошибка: тип '42' не присваивается типу 'string'

Примечание: Для отдельных строк можно отключить проверку типов с помощью // @ts-ignore.

Переименуйте файлы в .ts

Начните с некритичных файлов — переименуйте их из .js в .ts:


# Переименуйте один файл
mv src/utils/helpers.js src/utils/helpers.ts

# Или переименуйте все файлы в директории (используйте с осторожностью)
find src/utils -name "*.js" -exec sh -c 'mv "$0" "${0%.js}.ts"' {} \;

Добавьте аннотации типов

Постепенно добавьте аннотации типов в код:


// До
function add(a, b) {
  return a + b;
}

// После
function add(a: number, b: number): number {
  return a + b;
}

// С интерфейсом
interface User {
  id: number;
  name: string;
  email?: string;
}

function getUser(id: number): User {
  return { id, name: 'John Doe' };
}

Обновите скрипты сборки и тестирования

Измените package.json, добавив компиляцию TypeScript:


{
  "scripts": {
    "build": "tsc",
    "dev": "tsc --watch",
    "test": "jest"
  }
}

Примечание: Обновите конфигурацию тестов, чтобы они работали с TypeScript‑файлами.


Инструменты для миграции

ts-migrate

Автоматизированный инструмент для переноса JavaScript в TypeScript.


npx ts-migrate-full .

TypeStat

Преобразует JavaScript в TypeScript с сохранением типобезопасности.


npx typestat --init

Пакеты @types

Устанавливают определения типов для зависимостей:


npm install --save-dev @types/react @types/node


Лучшие практики при миграции на TypeScript

Начинайте с малого и постепенно двигайтесь вперед

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

Используйте возможности TypeScript

Пример


// Используйте вывод типов, где это возможно
const name = 'John'; // TypeScript выводит 'string'
const age = 30; // TypeScript выводит 'number'

// Используйте объединения типов для гибкости
type Status = 'active' | 'inactive' | 'pending';

// Используйте защитники типов для проверок во время выполнения
function isString(value: any): value is string {
  return typeof value === 'string';
}

Работа со сторонними библиотеками

  • установите пакеты @types для зависимостей;
  • создайте файлы объявлений для библиотек без типов;
  • используйте declare module для глобальных расширений типов.

Типичные проблемы и их решения

Динамические свойства

Проблема: В JavaScript часто используют объекты как словари.

Пример


// До
const user = {};
user.name = 'John'; // Ошибка: свойство 'name' не существует

Решение: Используйте сигнатуры индексов или утверждения типов.

Пример


// Вариант 1: сигнатура индекса
interface User {
  [key: string]: any;
}
const user: User = {};
user.name = 'John'; // OK

// Вариант 2: утверждение типа
const user = {} as { name: string };
user.name = 'John'; // OK

Контекст this

Проблема: Ошибки привязки this в обратных вызовах.

Пример


class Counter {
  count = 0;
  increment() {
    setTimeout(function() {
      this.count++; // Ошибка: 'this' не определён
    }, 1000);
  }
}

Решение: Используйте стрелочные функции или привяжите this.

Пример


// Решение 1: стрелочная функция
setTimeout(() => {
  this.count++; // 'this' лексически ограничен
}, 1000);

// Решение 2: привязка 'this'
setTimeout(function(this: Counter) {
  this.count++;
}.bind(this), 1000);


Заключение

Миграция с JavaScript на TypeScript — это значимое, но выгодное вложение в вашу кодовую базу.

Следуя этому руководству, вы сможете провести переход плавно и поэтапно.

Ключевые выводы:

  • Начните с надёжной конфигурации tsconfig.json.
  • Используйте опции allowJs и checkJs для постепенной миграции.
  • Задействуйте систему типов TypeScript, чтобы выявлять ошибки на ранних этапах.
  • Обновите процессы сборки и тестирования, чтобы обеспечить поддержку TypeScript.
  • Решайте типичные проблемы с помощью шаблонов, описанных выше.

Помните, что миграция — это процесс, а не разовое событие.

В переходный период допустимо иметь смешанную кодовую базу (с файлами .js и .ts).

Главное — продолжать двигаться вперёд, сохраняя качество кода.

Готовы начать миграцию?

Начните с настройки TypeScript в вашем проекте и постепенно добавляйте аннотации типов.

Компилятор TypeScript поможет вам сделать код более надёжным и удобным для поддержки.

Для получения дополнительной информации ознакомьтесь с официальным руководством по миграции на TypeScript.