Learn how stage 3 ECMAScript decorators in TypeScript 5.0+ intercept classes, methods, and accessors for logging and metadata.
Discover how TypeScript infers types automatically and how let versus const declarations shape wide types versus narrow literal types.
A Decorator is a special syntax (@decoratorName) that allows you to attach reusable aspect-oriented behavior (logging, validation, auto-binding) to classes, methods, fields, and accessors.
TypeScript 5.0 introduced support for the official Stage 3 ECMAScript Decorator standard without needing legacy experimentalDecorators flags!
A method decorator receives the original target function and a ClassMethodDecoratorContext object:
// Method Logger Decorator
function loggedMethod<This, Args extends any[], Return>(
target: (this: This, ...args: Args) => Return,
context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>
) {
const methodName = String(context.name);
return function (this: This, ...args: Args): Return {
console.log(`[LOG]: Entering method '${methodName}'...`);
const result = target.call(this, ...args);
console.log(`[LOG]: Exiting method '${methodName}'.`);
return result;
};
}
class UserService {
@loggedMethod
public deleteUser(id: string) {
console.log("Deleting user:", id);
}
}
const service = new UserService();
service.deleteUser("usr_42");
// Output:
// [LOG]: Entering method 'deleteUser'...
// Deleting user: usr_42
// [LOG]: Exiting method 'deleteUser'.
experimentalDecorators: true. Avoid mixing legacy experimental decorator syntax with modern standard decorators!Use decorators for clean aspect logging and ORM entity mapping. Next, let's finish our 30-lesson track with Project References and Monorepos!