What are Decorators in TypeScript?
Decorators are special functions that can be applied to classes, methods, properties or parameters to add or modify behavior at runtime or compile time.
Decorators are a kind of "annotations" or "modifiers" working at metadata level.
To work with decorators you need to enable flags:
{
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
Where can decorators be used?
- Classes
- Methods
- Properties
- Parameters
- Accessors (get/set)
Example: Class decorator
function Logger(constructor: Function) {
console.log(`Class created: ${constructor.name}`);
}
@Logger
class User {
constructor(public name: string) {}
}
The Logger decorator will be called when defining the User class, outputting the constructor name.
Example: Method decorator
function LogMethod(
target: any,
propertyKey: string,
descriptor: PropertyDescriptor
) {
const original = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`Method ${propertyKey} called with`, args);
return original.apply(this, args);
};
}
class MathService {
@LogMethod
sum(a: number, b: number) {
return a + b;
}
}
This decorator logs method call and its arguments.
Example: Property decorator
function Readonly(target: any, propertyKey: string) {
Object.defineProperty(target, propertyKey, {
writable: false,
});
}
class Config {
@Readonly
version = "1.0";
}
The version property is now impossible to change.
Example: Parameter decorator
function LogParam(target: Object, propertyKey: string | symbol, parameterIndex: number) {
console.log(`Method parameter ${String(propertyKey)} at position ${parameterIndex}`);
}
class Example {
test(@LogParam msg: string) {
console.log(msg);
}
}
Used rarely but can be useful for validation or logging.