Hack Frontend Community

What are Decorators in TypeScript?

Decorators are special functions that can be applied to classes, methods, properties or parameters to add or modify behavior at runtime or compile time.

Decorators are a kind of "annotations" or "modifiers" working at metadata level.

To work with decorators you need to enable flags:

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

Where can decorators be used?

  • Classes
  • Methods
  • Properties
  • Parameters
  • Accessors (get/set)

Example: Class decorator

function Logger(constructor: Function) {
  console.log(`Class created: ${constructor.name}`);
}

@Logger
class User {
  constructor(public name: string) {}
}

The Logger decorator will be called when defining the User class, outputting the constructor name.

Example: Method decorator

function LogMethod(
  target: any,
  propertyKey: string,
  descriptor: PropertyDescriptor
) {
  const original = descriptor.value;

  descriptor.value = function (...args: any[]) {
    console.log(`Method ${propertyKey} called with`, args);
    return original.apply(this, args);
  };
}

class MathService {
  @LogMethod
  sum(a: number, b: number) {
    return a + b;
  }
}

This decorator logs method call and its arguments.

Example: Property decorator

function Readonly(target: any, propertyKey: string) {
  Object.defineProperty(target, propertyKey, {
    writable: false,
  });
}

class Config {
  @Readonly
  version = "1.0";
}

The version property is now impossible to change.

Example: Parameter decorator

function LogParam(target: Object, propertyKey: string | symbol, parameterIndex: number) {
  console.log(`Method parameter ${String(propertyKey)} at position ${parameterIndex}`);
}

class Example {
  test(@LogParam msg: string) {
    console.log(msg);
  }
}

Used rarely but can be useful for validation or logging.