Транспиляция TypeScript: что умеет и чего не умеет esbuild

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

TypeScript добавляет в JavaScript систему статических типов, интерфейсы, перечисления и другие конструкции, которые не существуют в рантайме. Любой инструмент, который «транспилирует TypeScript», обязан удалить эти конструкции, чтобы получить валидный JavaScript. Именно эту задачу и решает esbuild.

При этом esbuild не является TypeScript-компилятором в полном смысле. Он не реализует семантический анализ типов и не выполняет проверку совместимости типов. Его роль ограничена синтаксическим преобразованием.


Что именно делает esbuild при обработке TypeScript

При включённой поддержке TypeScript esbuild выполняет строго ограниченный набор операций:

Удаление типов

  • интерфейсы (interface)
  • типовые аннотации (: string, : number)
  • generics (<T>)
  • type alias (type A = ...)

Трансформация современного синтаксиса

  • преобразование enum в JavaScript-эквиваленты
  • обработка декораторов (в зависимости от конфигурации)
  • трансформация optional chaining и nullish coalescing (если требуется по целевой среде)
  • преобразование import/export синтаксиса в формат, совместимый с выбранным бандлинг-режимом

Интеграция с модульной системой esbuild анализирует импорт/экспорт и может:

  • объединять модули в один файл (bundle mode)
  • сохранять ESM структуру
  • преобразовывать в CommonJS

Ключевая особенность: отсутствие type-checking

Главное ограничение esbuild в контексте TypeScript — полное отсутствие проверки типов.

Это означает:

  • некорректные типы не вызывают ошибок сборки
  • несовместимость интерфейсов не выявляется
  • ошибки использования API остаются незамеченными
  • tsconfig.json используется только частично (в основном для синтаксических опций)

Фактически esbuild «не знает», что такое типовая система TypeScript. Он рассматривает типы как комментарии, которые нужно удалить.


Последствия такого подхода

Отсутствие проверки типов приводит к смещению ответственности:

  • синтаксическая корректность обеспечивается esbuild
  • семантическая корректность (типы) должна обеспечиваться внешним инструментом

Обычно это означает параллельное использование tsc в режиме проверки:

  • tsc --noEmit — только проверка типов без генерации файлов
  • esbuild — быстрая трансформация и бандлинг

Такое разделение позволяет достичь высокой скорости сборки без потери типовой безопасности.


Поддерживаемые конструкции TypeScript

esbuild уверенно обрабатывает большинство распространённых возможностей TypeScript:

Базовые типы

  • string, number, boolean
  • массивы и кортежи
  • union и intersection (как синтаксис, без анализа)

Структуры кода

  • классы с модификаторами доступа (public, private, protected)
  • абстрактные классы
  • методы и свойства с типами

Функции

  • типизация параметров и возвращаемого значения
  • стрелочные функции с аннотациями

Модули

  • ES modules
  • namespace импортов (в ограниченном виде)

Ограничения транспиляции

Несмотря на высокую скорость и широкую поддержку синтаксиса, существуют принципиальные ограничения.

Отсутствие анализа типов

esbuild не умеет:

  • выводить типы (type inference)
  • проверять соответствие интерфейсам
  • анализировать generics на уровне логики
  • обнаруживать ошибки несовместимости типов

Частичная поддержка tsconfig

Многие опции TypeScript игнорируются:

  • noImplicitAny не применяется
  • strict не имеет эффекта
  • baseUrl и paths работают только через дополнительные механизмы резолвинга
  • сложные project references не поддерживаются

Ограничения декораторов

Поддержка декораторов зависит от версии и режима:

  • legacy decorators и stage 3 decorators обрабатываются по-разному
  • поведение может отличаться от tsc
  • некоторые edge-case сценарии несовместимы

Отличие от полноценного TypeScript-компилятора

Основное различие заключается в архитектуре:

  • TypeScript-компилятор (tsc) — это семантический анализатор + транспилятор
  • esbuild — это синтаксический трансформер + бандлер

Это приводит к фундаментальному разделению ответственности:

Возможность esbuild tsc
Удаление типов Да Да
Проверка типов Нет Да
Бандлинг Да Нет
Оптимизация сборки Да Ограниченно
Инкрементальная компиляция Да Да

Производительность и влияние на архитектуру сборки

Отказ от анализа типов делает esbuild крайне быстрым. В типичных сценариях он:

  • обрабатывает десятки тысяч файлов за миллисекунды
  • минимизирует задержки при разработке
  • снижает нагрузку на CI

Однако архитектура проекта должна учитывать:

  • необходимость отдельного этапа type-checking
  • невозможность полагаться на сборщик как на систему валидации кода
  • разделение pipeline на «build» и «type check»

Поведение при ошибочном TypeScript-коде

esbuild продолжает работу даже при наличии:

  • несоответствия типов
  • неверных generic-ограничений
  • неправильного использования интерфейсов

Ошибки проявляются только в двух случаях:

  • синтаксическая ошибка, нарушающая парсинг JavaScript/TypeScript
  • несовместимость конструкции с трансформацией

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


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

В реальных сборках TypeScript с esbuild обычно выстраивается двухэтапная схема:

  • этап 1: esbuild выполняет быстрый transpile + bundle
  • этап 2: tsc выполняет проверку типов без генерации файлов

Это позволяет:

  • сохранить строгую типизацию
  • ускорить разработку
  • избежать задержек полной компиляции

Особенности работы с JSX и TypeScript вместе

При использовании TSX:

  • esbuild удаляет типы из TSX-выражений
  • JSX преобразуется в вызовы функций (React runtime или automatic runtime)
  • типы React-элементов не проверяются

Это делает возможным использование React + TypeScript без замедления сборки, но переносит ответственность за корректность типов на внешний инструмент.


Итоговая характеристика поведения TypeScript в esbuild

Модель работы можно описать так:

  • TypeScript используется как расширение синтаксиса JavaScript
  • esbuild преобразует его в чистый JavaScript
  • вся система типов игнорируется на этапе сборки
  • безопасность типов достигается отдельным процессом проверки