Syntax
@decoratorName
class Name { }Examples
A Basic Class Decorator
A decorator that logs class instantiation.
function logged(target: Function) {
console.log(`Class defined: ${target.name}`);
}
@logged
class UserService {
constructor() {
console.log("UserService created");
}
}
new UserService();
// "Class defined: UserService" logs once, at class definition timeA Method Decorator
Wrapping a method to add behavior, like timing its execution.
function measure(target: any, context: ClassMethodDecoratorContext) {
return function (this: any, ...args: any[]) {
const start = performance.now();
const result = target.apply(this, args);
console.log(`${String(context.name)} took ${performance.now() - start}ms`);
return result;
};
}
class Calculator {
@measure
compute(n: number): number {
return n * n;
}
}Best practices
- Decorators are a stable, standard TypeScript feature as of the TC39 Stage 3 support landing in TypeScript 5.9 - no experimental flag is needed for the standard syntax
- Reach for decorators when building framework-level, cross-cutting functionality like dependency injection, validation, or logging - not as a general-purpose everyday tool
- Keep individual decorators focused on a single responsibility, similar to good middleware design
- When adopting a framework like Angular or NestJS, follow that framework's specific decorator conventions and configuration requirements closely, since they may build on this feature in framework-specific ways
Runtime & versions
Compiled to JavaScript. Feature availability depends on the language and runtime version used by your project; consult the official reference below.
TypeScript Handbook