Перейти к основному содержимому

Декораторы в TypeScript

Разработчику Архитектору

Дальше: Объекты и классы · Паттерны · Справочник — декораторы


Декораторы — синтаксис @annotation для классов, методов, полей и параметров. Они позволяют добавлять метаданные и обёртки декларативно. В экосистеме TS их знают по NestJS, TypeORM, class-validator — но они требуют настройки компилятора и дисциплины команды. Удобный порядок — классы, эта статья, TypeORM.

Полные таблицы — Справочник — декораторы. Обзор — Обзор TypeScript в JS.


Стандарт и версии

ЭтапСтатус
Legacy (experimental)experimentalDecorators + emitDecoratorMetadata
ECMAScript Stage 3новый синтаксис, useDefineForClassFields и др.
TS 5+постепенное выравнивание с ES decorators

Перед включением в проекте проверьте версию TypeScript и документацию фреймворка (Nest 10+, TypeORM 0.3+).

Минимальный tsconfig для legacy-стека:

{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"strict": true
}
}

Разбор:

  • emitDecoratorMetadata нужен для DI (reflect типов параметров конструктора) — увеличивает размер и связь с reflect-metadata.

Декоратор метода — логирование

Код ITЗагрузка примера кода…

Разбор:

  • Декоратор меняет descriptor.value — обёртка вокруг метода.
  • Типы unknown в обёртке — безопаснее any для args.

Декоратор класса (метаданные)

function Controller(path: string) {
return function <T extends { new (...args: unknown[]): object }>(ctor: T) {
Reflect.defineMetadata?.("path", path, ctor);
return ctor;
};
}

@Controller("/users")
class UsersController {}

В Nest путь и HTTP-метод задаются @Controller(), @Get() — тот же принцип.


Где декораторы уместны

СценарийПримеры
DI и маршрутыNestJS
ORM-сущностиTypeORM — TypeORM
Валидация DTOclass-validator
Cross-cuttingлог, метрики, права

Когда лучше без декораторов

СитуацияАльтернатива
Одна обёртка логированияфункция withLog(fn)
ВалидацияZod + safeParseРекомендации по разработке на TypeScript
Маршруты без Nestявная таблица routes
Команда не знает TS decoratorsявный код проще onboarding

Декораторы скрывают поток: сложнее отладка и понять, кто изменил метод.


Декораторы полей (TypeORM)


import { Entity, PrimaryGeneratedColumn, Column } from "typeorm";

@Entity("users")
export class User {
@PrimaryGeneratedColumn("uuid")
id!: string;

@Column({ unique: true })
email!: string;
}

Разбор:

  • ! — definite assignment assertion (поле заполнит ORM позже).
  • Схема БД и класс связаны декларативно — TypeORM.

Ограничения и риски

  • Порядок применения нескольких декораторов важен (снизу вверх / по спецификации).
  • Tree-shaking и статический анализ хуже, чем у plain functions.
  • Миграция legacy → ES decorators — плановая работа.

Частые ошибки

ОшибкаЧто делать
Включили decorators без reflect-metadata в entryimport "reflect-metadata" первым
any в DI параметрахявные типы токенов
Бизнес-логика в декораторетолько инфраструктура
Копировать Nest без Nestне та инфраструктура

Практика

  1. Реализуйте @LogCall и убедитесь, что бизнес-результат не изменился.
  2. Прочитайте один контроллер Nest и сопоставьте с таблицей маршрутов без фреймворка.
  3. Сравните валидацию: decorator и Zod на одном DTO.
  4. Проверьте tsconfig фреймворка из шаблона.
  5. Решите для своего pet-проекта: decorators да/нет и зафиксируйте в README.

Смежные статьи