Writing and Using Decorators in TypeScript

Decorators in TypeScript allow you to add functionality to existing classes, properties, or methods without modifying their original definitions. They provide a way to modify or extend the behavior of an object at runtime. Decorators allow you to separate the core logic of your code from the cross-cutting concerns, such as logging, caching, or authentication.

Creating Decorators

To define a decorator in TypeScript, you need to use the @ symbol followed by the decorator function or class. A decorator can be applied to a class, method, property, or parameter. Let's look at some examples:

Class Decorators

Class decorators are applied to the constructor of a class and can be used to modify the class declaration or behavior. Here is an example of a simple class decorator:

function logClass(target: Function) {
  console.log(`Class being decorated: ${target.name}`);
}

@logClass
class MyClass {
  // Class definition
}

In this example, the logClass decorator is applied to the MyClass declaration. When the decorator runs, it logs the name of the decorated class (MyClass) to the console.

Method Decorators

Method decorators are used to modify or add functionality to a specific method within a class. They are added before the method declaration and can access the method's descriptor, name, and other properties. Here's an example of a method decorator:

function logMethod(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
  console.log(`Method being decorated: ${propertyKey}`);
}

class MyClass {
  @logMethod
  myMethod() {
    // Method implementation
  }
}

In this example, the @logMethod decorator is applied to the myMethod method of the MyClass class. When the method is called, the decorator logs the name of the decorated method (myMethod) to the console.

Property Decorators

Property decorators are used to modify or add functionality to a specific property within a class. They are added before the property declaration and can access the property's name and constructor. Here's an example of a property decorator:

function logProperty(target: any, propertyKey: string) {
  console.log(`Property being decorated: ${propertyKey}`);
}

class MyClass {
  @logProperty
  myProperty: string;
}

In this example, the @logProperty decorator is applied to the myProperty property of the MyClass class. When the property is accessed or modified, the decorator logs the name of the decorated property (myProperty) to the console.

Parameter Decorators

Parameter decorators are used to modify or add functionality to a specific parameter within a method or constructor. They are added before the parameter declaration and can access the parameter's name, index, and constructor. Here's an example of a parameter decorator:

function logParameter(target: any, propertyKey: string, parameterIndex: number) {
  console.log(`Parameter being decorated: ${parameterIndex}`);
}

class MyClass {
  myMethod(@logParameter arg1: string, @logParameter arg2: number) {
    // Method implementation
  }
}

In this example, the @logParameter decorator is applied to the arg1 and arg2 parameters of the myMethod method in the MyClass class. When the method is called, the decorator logs the indices of the decorated parameters to the console.

Using Decorators

Decorators can be used to add various functionalities to your codebase. Some common use cases include:

  • Logging: Decorators can be used to log method calls, property access, or other relevant information.
  • Validation: Decorators can be used to validate method arguments or property values before executing the main logic.
  • Authorization: Decorators can be used to enforce access control rules before allowing execution of certain methods or property access.

To use a decorator, you simply apply it using the @ symbol before the target you want to decorate. The decorator function or class runs at runtime and modifies the behavior of the decorated element.

Conclusion

Decorators in TypeScript provide a powerful way to dynamically modify or extend the behavior of classes, methods, properties, and parameters. By separating cross-cutting concerns from the core logic of your code, decorators improve code readability, maintainability, and reusability. They enable you to apply reusable functionality to different parts of your codebase without modifying their original definitions.


noob to master © copyleft