← Back to TypeScript Course | Chapter 10: Decorators | Lesson 1 of 7

Introduction to Decorators

Decorators are functions that can observe or modify classes and class members in TypeScript. Modern TypeScript supports standard decorators for classes, methods, getters, setters, fields, and auto-accessors.

What Is a Decorator?

A decorator is a function applied with the @ syntax directly above a class, method, property, or parameter; it receives information about the declaration it's attached to and can observe or modify it.

Example: What Is a Decorator?

typescript
function logged(target: any, context: ClassMethodDecoratorContext) {
  console.log(`Decorator applied to ${String(context.name)}`);
}
class Greeter {
  @logged
  greet() {
    return "hi";
  }
}
new Greeter().greet();

Decorator Syntax

Decorators are written immediately before the declaration they decorate, and multiple decorators can be stacked on the same declaration, applying in a specific, well-defined order.

Example: Decorator Syntax

typescript
function first(target: any, ctx: ClassMethodDecoratorContext) {
  console.log("first decorator on", String(ctx.name));
}
function second(target: any, ctx: ClassMethodDecoratorContext) {
  console.log("second decorator on", String(ctx.name));
}
class Example {
  @first
  @second
  run() {}
}
new Example().run();

Decorator Context

Standard decorators receive a context object describing what is being decorated — its kind, name, and other metadata — which the decorator can use to decide how to behave.

Example: Decorator Context

typescript
function describe(target: any, context: ClassMethodDecoratorContext) {
  console.log("Decorating", context.kind, String(context.name));
}
class Service {
  @describe
  start() {}
}
new Service();

Replacing Decorated Values

Some decorators can return a compatible replacement value; method decorators, for example, commonly return a wrapped version of the original method that adds behavior like logging around the call.

Example: Replacing Decorated Values

typescript
function logCall(target: any, context: ClassMethodDecoratorContext) {
  return function (this: any, ...args: any[]) {
    console.log("Calling", String(context.name));
    return target.call(this, ...args);
  };
}
class Calculator {
  @logCall
  add(a: number, b: number) {
    return a + b;
  }
}
console.log(new Calculator().add(2, 3));

Enabling Modern Decorators

In current TypeScript, standard decorators work without needing the legacy experimentalDecorators compiler flag, following the newer, TC39-aligned decorators proposal instead of the older, non-standard implementation.

Example: Enabling Modern Decorators

typescript
// Modern (TC39) decorators work without experimentalDecorators:
function marker(target: any, context: ClassMethodDecoratorContext) {}
class Widget {
  @marker
  render() {
    return "rendered";
  }
}
console.log(new Widget().render());
🔒

Chapter Quiz — Complete all 7 topics to unlock

0/7 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.