Какой у тебя опыт работы с декораторами в TypeScript/Node.js?

Ответ

Я активно использую декораторы в TypeScript-проектах, особенно при работе с NestJS. Они отлично подходят для декларативного описания поведения классов и методов.

Практические примеры из моего опыта:

  1. Валидация: Создание кастомных декораторов для проверки входящих DTO.
  2. Логирование и профилирование: Обертывание методов для автоматического замера времени выполнения.

    function LogExecutionTime() {
      return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
        const originalMethod = descriptor.value;
        descriptor.value = async function (...args: any[]) {
          const start = performance.now();
          const result = await originalMethod.apply(this, args);
          const end = performance.now();
          console.log(`${propertyKey} executed in ${end - start}ms`);
          return result;
        };
        return descriptor;
      };
    }
    
    class UserService {
      @LogExecutionTime()
      async findAllUsers() {
        // ... логика запроса к БД
      }
    }
  3. Работа с NestJS: Использование встроенных декораторов (@Get(), @Post(), @UseGuards(), @Inject()) для построения контроллеров, провайдеров и модулей. Это основа dependency injection и структуры приложения в этом фреймворке.

Я включаю флаг "experimentalDecorators": true в tsconfig.json и слежу за прогрессом этой функциональности в стандарте ECMAScript.

Ответ 18+ 🔞

А, декораторы в TypeScript, да? Ну, ёпта, это вообще отдельная песня, особенно если ты, как я, влез в этот NestJS. Ты представляешь, какая это удобная штука — просто повесил волшебную бумажку на метод или класс, и всё, блядь, работает само. Не надо городить овердохуища кода вокруг простых действий.

Из моего опыта, если конкретно:

  1. Валидация. Ну, классика жанра. Вместо того чтобы в каждом методе контроллера руками проверять, что тебе пришло, пишешь один кастомный декоратор. Навесил его на DTO — и всё, хитрая жопа, которая пытается прислать ерунду, получит по рукам. Чисто, декларативно, красиво. Сам от себя охуевал, когда понял, насколько это упрощает жизнь.

  2. Логирование и замер времени. Вот смотри, реальный случай был. Надо понять, какой метод тормозит. Раньше бы начал везде console.time раскидывать, код превратился бы в помойку. А теперь? Ёперный театр, один декоратор на всё про всё!

    function LogExecutionTime() {
      return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
        const originalMethod = descriptor.value;
        descriptor.value = async function (...args: any[]) {
          const start = performance.now();
          const result = await originalMethod.apply(this, args);
          const end = performance.now();
          console.log(`${propertyKey} executed in ${end - start}ms`);
          return result;
        };
        return descriptor;
      };
    }
    
    class UserService {
      @LogExecutionTime()
      async findAllUsers() {
        // ... вот тут он, сука, к базе лезет и тормозит
      }
    }

    Навесил @LogExecutionTime() на сомнительный метод — и всё, блядь, он сам тебе в консоль плюнет, сколько там миллисекунд он копался. Удобство — просто пиздец.

  3. NestJS. Ну тут вообще без декораторов — нихуя. Это как хлеб без масла, суп без соли. Всё на них построено: @Get(), @Post() — чтобы роуты объявлять, @UseGuards() — чтобы доступ контролировать, @Inject() — чтобы зависимости подсовывать. Вся эта магия dependency injection и структура приложения — она на декораторах, как на костылях, стоит. Без них это просто куча беспомощного кода.

Да, и не забудь в tsconfig.json этот флаг "experimentalDecorators": true включить, а то будет тебе, чувак, хиросима с нигасраками — ничего работать не будет. Слежу, конечно, когда эту фичу в стандарт ECMAScript окончательно затолкают, а пока живём так. В целом, штука мощная, главное — не переборщить, а то можно такую мудю нагородить, что потом сам будешь ебать копать, разбираясь.