Компиляция
Процесс преобразования TypeScript-кода в JavaScript с проверкой типов, генерацией source maps и declaration-файлов.
Зачем нужно
- Браузеры и Node.js не понимают TypeScript напрямую — нужен JavaScript
- Компилятор
tscпроверяет типы и ловит ошибки до запуска кода - Source maps связывают скомпилированный JS с исходным TS для отладки
- Declaration files (
.d.ts) позволяют другим проектам использовать типы вашей библиотеки
Где используется
- В каждом TypeScript-проекте на этапе сборки
- CI/CD пайплайны запускают
tsc --noEmitдля проверки типов - Публикация npm-пакетов: генерация
.js+.d.ts - Разработка: watch mode для автоматической перекомпиляции
Предпосылки
- Что такое TypeScript — что такое TS
- Установка и tsconfig — настройка проекта
Базовая компиляция с tsc
Компиляция одного файла
# Компилирует app.ts → app.js
npx tsc app.ts
# С указанием целевой версии JS
npx tsc --target ES2020 app.ts
# Несколько файлов
npx tsc app.ts utils.ts helpers.ts
Компиляция проекта (через tsconfig.json)
# Компилирует всё по настройкам из tsconfig.json
npx tsc
# Указать конкретный конфиг
npx tsc --project tsconfig.production.json()
npx tsc -p tsconfig.production.json()
Проверка типов без генерации файлов
# Только проверка — файлы не создаются
npx tsc --noEmit
# Полезно для CI/CD и pre-commit хуков
Watch Mode — автоматическая перекомпиляция
# Следит за изменениями и перекомпилирует
npx tsc --watch
npx tsc -w
# С конкретным конфигом
npx tsc -w -p tsconfig.json
Watch mode отслеживает:
- Изменения в
.ts/.tsxфайлах - Добавление и удаление файлов
- Изменения в
tsconfig.json
# Пример вывода watch mode
[12:00:00] Starting compilation in watch mode...
[12:00:01] Found 0 errors. Watching for file changes.
# После изменения файла:
[12:00:15] File change detected. Starting incremental compilation...
[12:00:15] Found 0 errors. Watching for file changes.
Оптимизированный watch
// tsconfig.json
{
"watchOptions": {
// Стратегия наблюдения за файлами
"watchFile": "useFsEvents", // Использовать события FS (быстрее)
"watchDirectory": "useFsEvents", // Для директорий тоже
// Отложенная компиляция для пакетных изменений
"fallbackPolling": "dynamicPriority",
// Исключить ненужные директории из наблюдения
"excludeDirectories": ["node_modules", "dist"]
}
}
Source Maps
Source maps связывают скомпилированный JavaScript с исходным TypeScript. Это позволяет отлаживать TS-код прямо в браузере или в отладчике Node.js.
Включение source maps
// tsconfig.json
{
"compilerOptions": {
"sourceMap": true // Генерирует .js.map файлы
}
}
src/
index.ts
dist/
index.js ← скомпилированный JS
index.js.map ← source map (связь JS → TS)
Inline source maps
{
"compilerOptions": {
// Source map встраивается прямо в JS-файл (base64)
"inlineSourceMap": true,
// Исходный TS-код тоже встраивается в map
"inlineSources": true
}
}
Использование source maps
# Node.js автоматически подхватывает .map файлы
node --enable-source-maps dist/index.js
# В браузере source maps подхватываются DevTools автоматически
// src/index.ts
function divide(a: number, b: number): number {
if (b === 0) {
throw new Error("Division by zero"); // Строка 3 в TS
}
return a / b;
}
divide(10, 0);
// Стек ошибки покажет src/index.ts:3, а не dist/index.js:5
Declaration Files (.d.ts)
Declaration files содержат только описания типов без реализации. Они нужны чтобы TypeScript мог проверять типы при использовании вашего кода.
Генерация declaration files
// tsconfig.json
{
"compilerOptions": {
"declaration": true, // Генерировать .d.ts
"declarationDir": "./types", // Куда складывать (опционально)
"declarationMap": true // Связь .d.ts → .ts для Go to Definition
}
}
Пример генерации
// src/math.ts (исходник)
export function add(a: number, b: number): number {
return a + b;
}
export interface MathResult {
value: number;
operation: string;
}
// dist/math.d.ts (сгенерированный declaration file)
export declare function add(a: number, b: number): number;
export interface MathResult {
value: number;
operation: string;
}
Только declaration (без JS)
{
"compilerOptions": {
"declaration": true,
"emitDeclarationOnly": true // Только .d.ts, без .js
}
}
Это полезно когда JS генерируется другим инструментом (esbuild, Babel, SWC), а tsc используется только для типов.
Инкрементальная компиляция
Инкрементальная компиляция сохраняет информацию о предыдущей сборке и при следующем запуске перекомпилирует только изменённые файлы.
// tsconfig.json
{
"compilerOptions": {
"incremental": true, // Включить инкрементальную компиляцию
"tsBuildInfoFile": "./.tsbuildinfo" // Файл с информацией о сборке
}
}
# Первая компиляция — полная (создаёт .tsbuildinfo)
npx tsc
# Build time: 5.2s
# Вторая компиляция — инкрементальная (перекомпилирует только изменённое)
npx tsc
# Build time: 0.8s
Composite (для project references)
{
"compilerOptions": {
"composite": true // Включает incremental + declaration + ещё проверки
}
}
# Собирает проект с учётом зависимостей между подпроектами
npx tsc --build
npx tsc -b
# Очистка артефактов
npx tsc -b --clean
# Force перекомпиляция
npx tsc -b --force
Этапы компиляции TypeScript
1. Parsing → AST (Abstract Syntax Tree)
2. Binding → Связывание символов (переменные, функции)
3. Type Checking → Проверка типов (основная работа!)
4. Emit → Генерация .js, .d.ts, .map файлов
// Стадия 1: Parsing — создание AST
const x: number = "hello";
// AST: VariableDeclaration -> TypeAnnotation(number) -> StringLiteral("hello")
// Стадия 3: Type Checking — обнаружение ошибки
// Error: Type 'string' is not assignable to type 'number'
// Стадия 4: Emit — (не выполнится из-за ошибки, или выполнится с noEmitOnError: false)
Контроль emit при ошибках
{
"compilerOptions": {
// Не генерировать JS если есть ошибки типов (по умолчанию false!)
"noEmitOnError": true
}
}
Альтернативные инструменты компиляции
tsc — не единственный способ компилировать TypeScript:
| Инструмент | Скорость | Проверка типов | Использование |
|---|---|---|---|
tsc |
Средняя | Да | Стандартный компилятор |
esbuild |
Очень быстрая | Нет | Бандлинг, dev-сервер |
SWC |
Очень быстрая | Нет | Next.js, Parcel |
Babel |
Быстрая | Нет | Webpack, legacy |
tsx |
Быстрая | Нет | Запуск TS в Node.js |
ts-node |
Средняя | Да (опционально) | Запуск TS в Node.js |
Типичный pipeline
# Проверка типов — tsc
npx tsc --noEmit
# Компиляция/бандлинг — быстрый инструмент
npx esbuild src/index.ts --bundle --outfile=dist/index.js
// package.json
{
"scripts": {
"typecheck": "tsc --noEmit",
"build": "esbuild src/index.ts --bundle --outdir=dist --platform=node",
"dev": "tsx watch src/index.ts",
"start": "node dist/index.js"
}
}
Полезные флаги CLI
# Показать все файлы, которые tsc собирается компилировать
npx tsc --listFiles
# Показать время каждого этапа компиляции
npx tsc --diagnostics
# Расширенная диагностика
npx tsc --extendedDiagnostics
# Показать итоговую конфигурацию (с учётом extends и defaults)
npx tsc --showConfig
# Вывести список поддерживаемых опций
npx tsc --help
npx tsc --all # все опции
# Сгенерировать trace для анализа производительности
npx tsc --generateTrace ./trace
Частые ошибки
- Забыть
noEmitOnError: true— tsc генерирует JS даже при ошибках типов - Не использовать
incremental— каждая компиляция полная и медленная - Watch mode не видит новые файлы — перезапустите
tsc -wили проверьтеinclude - Source maps не работают — убедитесь что
"sourceMap": trueи файл.mapрядом с.js - Медленная компиляция — используйте
skipLibCheck: true,incremental: true
# Диагностика медленной компиляции
npx tsc --extendedDiagnostics
# Вывод покажет:
# Files: 1234
# Lines: 56789
# Parse time: 1.23s
# Bind time: 0.45s
# Check time: 3.67s ← основное время
# Emit time: 0.89s
# Total time: 6.24s
- Разница между
tscи бандлером — бандлеры (esbuild, SWC) не проверяют типы, только удаляют аннотации
Практика
- Создайте проект с
src/index.tsиtsconfig.json - Скомпилируйте с
sourceMap: true— изучите файл.js.map - Запустите
tsc -w— поменяйте файл и наблюдайте перекомпиляцию - Добавьте
declaration: true— посмотрите на.d.tsфайлы - Включите
incremental: true— сравните время первой и второй компиляции - Попробуйте
tsc --noEmitв CI-скрипте
Связанные темы
- Установка и tsconfig — настройка tsconfig.json
- Declaration files (.d.ts) — подробнее про declaration files
- Модули TS — система модулей и импорты
- Strict mode в TS — строгий режим