Декораторы в TypeScript представляют собой механизм метапрограммирования, позволяющий модифицировать классы, методы, свойства и параметры на этапе определения. Несмотря на то, что синтаксис выглядит стабильным, его семантика долгое время находилась в стадии эволюции, что напрямую повлияло на инструменты сборки, включая esbuild.
В TypeScript существует два основных режима работы с декораторами:
Эти два подхода несовместимы по поведению, что критично для сборщиков и транспайлеров.
Legacy-декораторы активируются при включении следующих опций в
tsconfig.json:
experimentalDecorators: trueemitDecoratorMetadata: true (опционально)Основные особенности:
Декораторы применяются снизу вверх, справа налево, что влияет на композицию модификаторов.
Декоратор может заменить:
При использовании emitDecoratorMetadata TypeScript
генерирует метаданные типов, доступные через
reflect-metadata.
Пример поведения:
design:type,
design:paramtypesLegacy-декораторы требуют выполнения дополнительного JavaScript-кода после транспиляции.
Современный стандарт декораторов (Stage 3) изменяет модель работы:
Ключевые изменения:
Декоратор теперь получает контекст:
Больше нельзя произвольно перезаписывать дескрипторы методов.
Поведение декораторов становится ближе к функциональному программированию.
| Характеристика | Legacy | Stage 3 |
|---|---|---|
| Статус | устаревающий | стандарт ECMAScript |
| Изменение метода | возможно | ограничено |
| Метаданные | reflect-metadata | встроенные |
| Совместимость | широкая | ограниченная |
| Использование в фреймворках | массовое | постепенно внедряется |
esbuild ориентирован на сверхбыструю трансформацию кода, но его подход к декораторам ограничен архитектурно.
esbuild не является TypeScript-компилятором. Он:
Из-за этого:
emitDecoratorMetadata не поддерживаетсяesbuild поддерживает базовую трансформацию legacy-декораторов при включении:
--target=esnext--loader=tsОднако поведение имеет ограничения:
Поддержка stage 3 декораторов в esbuild:
Ключевая проблема:
Следствие:
design:typeБиблиотека reflect-metadata требует:
esbuild этого не обеспечивает.
esbuild использует собственный оптимизированный парсер:
Фреймворки, завязанные на декораторы:
требуют осторожной интеграции с esbuild.
Часто возникает необходимость:
Типовая схема при использовании декораторов:
TypeScript (tsc) → esbuild (bundle/minify)
или
Babel (decorators transform) → esbuild
Без дополнительного шага:
В экосистеме декораторов часто применяются альтернативы:
@babel/plugin-proposal-decoratorsКлючевые параметры, влияющие на поведение декораторов:
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}
При использовании esbuild:
Метаданные становятся undefined или отсутствуют
полностью.
В сложных композициях возможны расхождения с поведением tsc.
Системы инверсии зависимостей перестают корректно резолвить типы.
Проблемы проявляются только в рантайме:
Декораторы постепенно переходят из экспериментальной зоны в стандарт ECMAScript, однако экосистема инструментов развивается асинхронно:
Это формирует устойчивую архитектурную модель: