Декоратор — функция, которая наблюдает или подменяет объявление в момент определения — выполняется один раз при объявлении класса, не на каждый инстанс. Ловушка, о которой редко предупреждают: сейчас две несовместимые системы — legacy TypeScript experimentalDecorators (Angular, NestJS, TypeORM) и стандарт TC39 Stage 3 (TS 5.0+, default). Сигнатуры разные, смешивать нельзя.
@logged class Foo {} ≈ Foo = logged(Foo) ?? Foo. Срабатывает когда класс вычисляется, даёт шанс осмотреть, обернуть или заменить объявление. Это не хук на каждый вызов и не бесплатная магия — обычный вызов функции, который компилятор вшивает в место декларации.
Главный факт: «декораторы» — два разных языка с одним синтаксисом. Назвать, какая система в кодовой базе и почему они не сосуществуют — уже сильный ответ.
Итог
Декоратор = metaprogramming на этапе объявления; legacy vs Stage 3 — ключевое различие.