How to Use Decorators in TypeScript
Decorators in TypeScript are a powerful feature that enables developers to add extra functionality to classes, methods, properties, and parameters. They provide a way to modify the behavior of existing code without changing its actual structure. This guide will explain how to use decorators in TypeScript with easy-to-follow examples.
What are Decorators?
Decorators are special functions that can be applied to classes, methods, properties, or parameters. They are invoked at runtime and allow developers to annotate and modify code in a declarative way. To enable decorators in a TypeScript project, the experimentalDecorators
flag must be set to true
in the tsconfig.json
file.
Enabling Decorators in TypeScript
To use decorators, the TypeScript compiler must be configured to recognize them. This can be done by setting the experimentalDecorators
flag to true
in the tsconfig.json
file.
{
"compilerOptions": {
"target": "ES6",
"experimentalDecorators": true
}
}
Once decorators are enabled, they can be used throughout the project.
Creating a Class Decorator
A class decorator is applied to a class declaration and can be used to modify or replace a class definition. Class decorators are declared just above the class they decorate, using the @
symbol.
function LogClass(target: Function) {
console.log(`Class ${target.name} is created.`);
}
@LogClass
class Person {
constructor(public name: string) {}
}
const person = new Person('Alice');
In this example, the LogClass
decorator logs a message when the Person
class is created. The decorator is defined as a function that takes a single argument: the constructor of the class being decorated.
Method Decorators
Method decorators are applied to methods within a class. They allow developers to intercept method calls, modify their behavior, or perform additional operations before or after the method is executed.
function LogMethod(target: Object, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`Method ${propertyKey} is called with arguments: ${args}`);
return originalMethod.apply(this, args);
};
return descriptor;
}
class Calculator {
@LogMethod
add(a: number, b: number): number {
return a + b;
}
}
const calc = new Calculator();
calc.add(2, 3);
Here, the LogMethod
decorator logs the method name and its arguments whenever the add
method is called. It wraps the original method in a new function that performs the logging before delegating to the original method.
Property Decorators
Property decorators are used to observe or modify the behavior of class properties. Unlike method decorators, they do not have access to the property value itself, but they can add metadata to properties.
function ReadOnly(target: Object, propertyKey: string) {
Object.defineProperty(target, propertyKey, {
writable: false
});
}
class Book {
@ReadOnly
title: string = 'TypeScript Guide';
}
const myBook = new Book();
myBook.title = 'New Title'; // This will cause an error in strict mode
In this example, the ReadOnly
decorator is applied to the title
property of the Book
class, making it read-only by setting writable
to false
.
Parameter Decorators
Parameter decorators are used to annotate or modify method parameters. They receive three arguments: the target object, the method name, and the parameter index.
function LogParameter(target: Object, propertyKey: string, parameterIndex: number) {
console.log(`Parameter in position ${parameterIndex} at ${propertyKey} method is decorated.`);
}
class UserService {
greet(@LogParameter message: string): void {
console.log(message);
}
}
const userService = new UserService();
userService.greet('Hello, TypeScript!');
In this example, the LogParameter
decorator is applied to the message
parameter of the greet
method in the UserService
class. The decorator logs information about the parameter being decorated.
Conclusion
Decorators in TypeScript offer a powerful way to enhance code functionality without altering its structure. By leveraging class, method, property, and parameter decorators, developers can easily add reusable functionality across their projects. With the examples provided in this guide, it's easy to get started with using decorators in TypeScript.