Creating a custom decorator in TypeScript involves defining a function with a specific signature that TypeScript recognizes as a decorator. Decorators can be applied to classes, class properties, methods, accessors, and method parameters. In this explanation, I will provide detailed steps to create a custom class decorator, method decorator, and property decorator.
Let’s start with a class decorator. A class decorator is a function that takes a constructor as its argument and returns either void or a new constructor (if you want to replace the class):
function ClassDecorator<T extends { new(...args: any[]): {} }>(constructor: T) {
// Perform operations on the constructor, e.g., add or modify methods.
return class extends constructor {
// Add or override properties or methods.
};
}
Usage example:
@ClassDecorator
class MyClass {
constructor(public name: string) {}
}
const myInstance = new MyClass("John Doe");
Next, let’s create a custom method decorator. A method decorator is a function that takes three arguments: target (the prototype of the class), propertyKey (method name), and descriptor (property descriptor), and returns a new descriptor or void:
function MethodDecorator(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor | void {
// Perform operations on the descriptor or the target, e.g., modify the method implementation.
}
Usage example:
class AnotherClass {
@MethodDecorator
sayHello(name: string): string {
return `Hello, ${name}!`;
}
}
Lastly, let’s create a custom property decorator. A property decorator is a function that takes two arguments: target (the prototype of the class) and propertyKey (property name), and returns nothing:
function PropertyDecorator(target: Object, propertyKey: string | symbol): void {
// Perform operations on the target or create/modify metadata.
}
Usage example:
class ThirdClass {
@PropertyDecorator
public greeting: string;
constructor(greeting: string) {
this.greeting = greeting;
}
}
That’s it! Now you know how to create custom decorators in TypeScript for classes, methods, and properties. Just make sure that you have enabled the "experimentalDecorators" option in your ‘tsconfig.json‘ file:
{
"compilerOptions": {
"experimentalDecorators": true
}
}