In TypeScript, decorators are a special type of declaration that can be attached to class declarations, methods, accessors, properties, or parameters. Decorators use the @expression syntax, where the expression must evaluate to a function that is called at runtime, with the information about the decorated declaration passed as arguments.
Creating Custom Decorators: Steps
- Enable Decorator Features: First, ensure that decorator functionality is enabled in the
tsconfig.jsonfile:
json{ "compilerOptions": { "experimentalDecorators": true, "target": "ES5" } }
- Write Decorator Functions: Decorator functions can receive different parameters depending on whether the decorator is applied to a class, method, property, parameter, or accessor.
- Class Decorator: Receives one parameter, which is the class constructor.
typescriptfunction ClassDecorator(constructor: Function) { console.log("Class decorator called"); console.log(constructor); }
- Method Decorator: Receives three parameters: the target object, property name, and property descriptor.
typescriptfunction MethodDecorator(target: Object, propertyKey: string, descriptor: PropertyDescriptor) { console.log("Method decorator called"); console.log(target); console.log(propertyKey); console.log(descriptor); }
-
Accessor/Property Decorator: Same parameters as method decorators.
-
Parameter Decorator: Receives three parameters: the target object, method name, and index of the parameter in the function parameter list.
typescriptfunction ParamDecorator(target: Object, propertyKey: string, index: number) { console.log("Parameter decorator called"); console.log(target); console.log(propertyKey); console.log(index); }
- Apply Decorators: Apply decorators to the corresponding classes, methods, properties, etc.
typescript@ClassDecorator class ExampleClass { @MethodDecorator method() {} @ParamDecorator methodWithParams(@ParamDecorator param1: string) {} }
Example:
Here is a concrete example where a class decorator is defined that simply logs the class name and some debugging information:
typescriptfunction LogClassName(target: Function) { console.log(`Class name is: ${target.name}`); } @LogClassName class MyExampleClass { constructor(public name: string) {} } let obj = new MyExampleClass("Example class");
In this example, when MyExampleClass is defined, the LogClassName decorator is called and outputs the class name MyExampleClass.
Decorators are a powerful feature in TypeScript that allow developers to enhance the behavior of classes, methods, and properties while maintaining code clarity and maintainability.