Миграция JS в TS

Пошаговая стратегия перевода JavaScript-проекта на TypeScript.

Зачем нужно

  • Типобезопасность для существующего кода
  • Лучшая поддержка IDE (автодополнение, рефакторинг)
  • Постепенный переход без переписывания всего сразу

Где используется

  • Любой JS-проект, который хотят типизировать

Стратегия миграции

1. Подготовка

npm i -D typescript @types/node
npx tsc --init
{
  "compilerOptions": {
    "allowJs": true,
    "checkJs": false,
    "strict": false,
    "outDir": "./dist",
    "rootDir": "./src",
    "module": "ESNext",
    "moduleResolution": "bundler"
  },
  "include": ["src"]
}

2. Переименование файлов (.js -> .ts)

Начни с файлов без зависимостей (утилиты, константы):

utils.js → utils.ts
config.js → config.ts

3. Добавление типов постепенно

// Было (JS)
function getUser(id) {
  return fetch(`/api/users/${id}`).then(r => r.json());
}

// Стало (TS)
interface User {
  id: number;
  name: string;
  email: string;
}

async function getUser(id: number): Promise<User> {
  const res = await fetch(`/api/users/${id}`);
  return res.json();
}

4. Включение strict постепенно

// Шаг 1: noImplicitAny
{ "noImplicitAny": true }

// Шаг 2: strictNullChecks
{ "strictNullChecks": true }

// Шаг 3: всё остальное
{ "strict": true }

5. JSDoc как промежуточный шаг

Для файлов, которые пока нельзя переименовать:

// @ts-check
/** @param {string} name */
/** @returns {number} */
function getLength(name) {
  return name.length;
}

Чеклист

  • Установить TS и настроить tsconfig
  • Добавить @types/* для зависимостей
  • Переименовать файлы от листьев к корню
  • Убрать any и добавить интерфейсы
  • Включить strict: true

Связанные темы

Ресурсы