Интеграция с JavaScript
Интеграция с JavaScript
Технический фундамент миграции JS -> TS
У стабильной миграции есть техническая стратегия:
- типизировать сначала модули с высоким риском и большим числом зависимостей;
- постепенно ужесточать
tsconfig, а не включать максимум строгости сразу; - явно типизировать границы между legacy JS и новым TS;
- держать временные
anyлокальными и отслеживаемыми.
Это позволяет повышать надежность системы без "заморозки" продуктовой разработки.
Почему интеграция важнее "идеальной миграции"
В реальности редко бывает проект, который с нуля полностью на TypeScript. Чаще есть существующий JavaScript-код, и TypeScript внедряют постепенно. Главная задача не "переписать всё за неделю", а безопасно повышать качество без остановки разработки.
Ключевой момент: успешная интеграция TS в JS-проект это поэтапная стратегия, а не одномоментный рефакторинг.
Проверь себя: почему попытка мгновенно типизировать весь legacy-код часто приводит к срыву сроков?
Пошаговый старт
Обычно начинают так:
- Добавляют TypeScript в сборку.
- Создают
tsconfig.jsonс умеренно строгими настройками. - Переводят новые файлы в
.ts/.tsx. - Постепенно типизируют критичные JS-модули.
Это позволяет получать пользу от TS сразу, не ломая текущий процесс.
Работа с существующим JavaScript
TypeScript умеет проверять и .js файлы в режиме checkJs.
// @ts-check
/** @param {number} a @param {number} b */
function sum(a, b) {
return a + b;
}
Даже без полного перехода на .ts можно добавить базовую типовую дисциплину через JSDoc.
Смотри, что важно: это хороший мост для больших legacy-проектов.
Анти-провал: если нужно временно подавить типовую ошибку, чаще предпочтительнее // @ts-expect-error, чем // @ts-ignore. Первая конструкция заставит тебя вернуться и убрать "костыль", когда ошибка исчезнет.
// @ts-expect-error временный мост: контракт legacy-кода описан неверно
legacyCall();
Внешние библиотеки и типы
Для библиотек нужны типовые декларации. Часто они уже есть в пакете или в @types/....
Если типов нет, можно:
- добавить минимальную декларацию вручную (
.d.ts); - временно использовать
anyлокально, но с планом замены.
declare module 'legacy-analytics' {
export function track(event: string, payload?: unknown): void;
}
Проверь себя: почему лучше написать минимальный .d.ts, чем размазать any по всему проекту?
Границы между TS и JS
На границе модулей полезно делать явную нормализацию и валидацию входа.
type User = { id: number; name: string };
function toUser(raw: unknown): User | null {
if (typeof raw === 'object' && raw !== null && 'id' in raw && 'name' in raw) {
const r = raw as { id: unknown; name: unknown };
if (typeof r.id === 'number' && typeof r.name === 'string') {
return { id: r.id, name: r.name };
}
}
return null;
}
Это защищает TS-код от неконтролируемых JS-данных.
Реальные микро-сценарии
- Постепенный переход фронтенда.
Новые компоненты пишутся на TS, старые JS-компоненты остаются, пока есть приоритет бизнеса.
- Node.js сервис.
Критичные модули (валидация, расчеты, контракты API) переводятся в TS первыми.
- Монорепа.
Общие пакеты типизируются раньше, чтобы дать безопасные контракты всем потребителям.
Частые ошибки новичков
- Включать максимальную строгость сразу на весь legacy-код.
- Массово ставить
anyбез плана устранения. - Пытаться типизировать низкоприоритетные модули раньше критичных.
- Игнорировать границы данных между JS и TS.
Анти-провал: миграцию планируй по ценности - сначала места с высоким риском багов и большим числом зависимостей.
Что будет, если изменить входные данные
Если JS-модуль начнет отдавать поле другого типа, строго типизированный TS-код подсветит несовместимость при интеграции. Без этого проблема всплыла бы позже в рантайме. Поэтому границы модулей - главная точка, где TypeScript дает максимальный эффект.
Проверь себя: какие 2-3 модуля в типичном проекте ты бы типизировал первыми и почему?
Краткий итог
- Интеграция TS в JS-проект должна быть постепенной и управляемой.
checkJsи JSDoc помогают начать без полного переписывания.- На границах данных нужны явные проверки и нормализация.
- Работа с типами внешних библиотек критична для надежных контрактов.
- Успешная миграция - это баланс скорости разработки и роста типовой безопасности.