Fundamentals 10 min read

A Comprehensive Guide to JavaScript/TypeScript Decorators and Their Practical Use

The guide explains JavaScript/TypeScript decorators—an ECMAScript stage‑2 proposal used in frameworks like Angular, Nest.js, and TypeORM—by distinguishing the decorator pattern, function, and @syntax, demonstrating a four‑step manual implementation that logs execution time, and linking decorators to AOP, IoC, and DI concepts.

Tencent Cloud Developer
Tencent Cloud Developer
Tencent Cloud Developer
A Comprehensive Guide to JavaScript/TypeScript Decorators and Their Practical Use

While reading the VS Code source code, the author discovered extensive use of the @Decorator syntax, which was unfamiliar. Decorators are also heavily used in frameworks such as Angular, Nest.js, TypeORM, Mobx, and Theia. This article explains the principles and usage of decorators.

Decorators are an ECMAScript stage‑2 proposal, but TypeScript or Babel enable their use today. Understanding decorators is essential for grasping advanced concepts like AOP (Aspect‑Oriented Programming), IoC (Inversion of Control), and DI (Dependency Injection) that appear in many popular projects.

Example of a Nest.js controller using @Controller and @Get decorators:

/* Nest.Js cats.controller.ts */
import { Controller, Get } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Get()
  findAll(): string {
    return 'This action returns all cats';
  }
}

The article then distinguishes three related concepts:

Decorator Pattern : an abstract design idea that extends functionality without modifying the original code.

Decorator (function) : a concrete implementation of the pattern as a special class‑level function.

@Decorator syntax : a syntactic sugar that requires compilation before execution.

To illustrate practical usage, a four‑step manual implementation of a decorator that logs function execution time is presented.

// decorator function
function decoratorLogTime(target, key) {
  const targetPrototype = target.prototype;
  // Step1: backup original descriptor
  const oldDescriptor = Object.getOwnPropertyDescriptor(targetPrototype, key);
  // Step2: create wrapper with before/after hooks
  const logTime = function (...arg) {
    let start = +new Date();
    try {
      return oldDescriptor.value.apply(this, arg);
    } finally {
      let end = +new Date();
      console.log(`耗时: ${end - start}ms`);
    }
  };
  // Step3: replace descriptor value with wrapper
  Object.defineProperty(targetPrototype, key, {
    ...oldDescriptor,
    value: logTime
  });
}

// usage example
class GuanYu {
  attack() { console.log('挥了一次大刀'); }
  run() { console.log('跑了一段距离'); }
}
// Apply decorator manually to both methods
decoratorLogTime(GuanYu, 'attack');
decoratorLogTime(GuanYu, 'run');

const guanYu = new GuanYu();
guanYu.attack(); // 挥了一次大刀  耗时: 0ms
guanYu.run();   // 跑了一段距离  耗时: 0ms

The steps are explained in detail:

Step 1 : Use Object.getOwnPropertyDescriptor to retrieve the original property descriptor.

Step 2 : Write the wrapper function that records the start time, invokes the original method, and logs the elapsed time in a finally block.

Step 3 : Replace the original descriptor’s value with the wrapper via Object.defineProperty .

Step 4 : Manually invoke the decorator for the desired class methods.

The article also discusses related architectural concepts:

AOP : separates cross‑cutting concerns (logging, performance monitoring, security) from business logic.

IoC : inverts control flow so that frameworks manage object creation and lifecycle.

DI : a concrete implementation of IoC that injects dependencies into classes.

Illustrative diagrams (omitted here) show how AOP and IoC reduce coupling and improve maintainability.

Basic APIs required for decorator implementation are highlighted:

Object.getOwnPropertyDescriptor() – retrieves a property’s descriptor.

Object.defineProperty() – defines or modifies a property descriptor.

Author bio: Eason Ruan, senior front‑end engineer at Tencent, core developer of the WeDa low‑code platform, with extensive experience in large‑scale front‑end projects.

Design PatternsPerformanceTypeScriptAOPIoCJavaScriptdecorator
Tencent Cloud Developer
Written by

Tencent Cloud Developer

Official Tencent Cloud community account that brings together developers, shares practical tech insights, and fosters an influential tech exchange community.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.