Annotations That Wrap Classes and Methods
Decorators
Decorators are functions that modify classes, methods, fields, or accessors. They're a real JS feature (Stage 3) as of 2023.
What you'll learn
- Author a simple method decorator
- Apply a decorator to a class
- Understand the modern (TC39 Stage 3) form
A decorator is a function that runs at class definition time to wrap or modify a class, method, accessor, or field. TS 5+ ships the modern TC39 (Stage 3) form.
A Method Decorator
function log(target: Function, context: ClassMethodDecoratorContext) {
return function (this: unknown, ...args: unknown[]) {
console.log(`[call] ${String(context.name)}(${args.join(", ")})`);
return target.call(this, ...args);
};
}
class Calculator {
@log
add(a: number, b: number) {
return a + b;
}
}
new Calculator().add(1, 2);
// [call] add(1, 2)
// 3 @log runs once when the class is defined. It receives the
original method and returns a replacement that logs, then
delegates.
A Class Decorator
function sealed(target: Function, context: ClassDecoratorContext) {
Object.seal(target);
Object.seal(target.prototype);
}
@sealed
class Point {
x = 0; y = 0;
} Runs on the class itself — at definition time.
Common Uses
- Logging / tracing
- Validation (NestJS, class-validator)
- Dependency injection (NestJS, Inversify)
- ORM column mappings (TypeORM)
Enabling
The modern decorators are on by default in TS 5+. For the older “experimental” form (Angular, NestJS-style):
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
} Note: the old and new forms have different function signatures and behavior. Pick one for a project — don’t mix.
When To Reach For Them
Decorators add a layer of magic — useful in framework code, less useful in everyday app logic. A plain higher-order function often beats a decorator for clarity.
Up Next
Enums — TS’s named-constant feature, complete with its share of gotchas.
Enums →