How to use decorators in TypeScript

Decorators are a powerful feature in TypeScript that allows developers to control the behavior of classes, methods, properties, and parameters. They provide an effective way to organize code, separate concerns, and promote code reuse.

Basics of decorators in TypeScript

To define a decorator, we write a function that takes the target element as its argument and returns a new value or performs some action. The decorator function is then applied using the @ symbol, followed by the decorator name, placed just before the target element declaration.

There are four main types of decorators in TypeScript:

  • Parameter decorators: These are applied to the parameters of a method or constructor, allowing us to manipulate or add metadata to the parameters.

  • Class decorators: These are applied to classes, allowing us to modify their behavior or add metadata.

  • Method decorators: These are applied to methods within a class, enabling us to alter their behavior or add additional functionality.

  • Property decorators: These are applied to class properties, providing a way to modify their behavior or add metadata.

In TypeScript, the evaluation order of decorators is structured to ensure consistency and predictability during the decoration process. The order in which decorators are invoked follows a clear pattern:

  • For each instance member, Parameter decorators take precedence, succeeded by Method, Accessor, or Property decorators.

  • For each static member, Parameter decorators have priority, followed by Method, Accessor, or Property decorators.

  • Parameter decorators are designated for the constructor.

  • Class decorators are meant for the entire class structure.

In object-oriented programming, instance members refer to the properties and methods of a class's instances (objects). These members are unique to each instance and can have different values or states.

On the other hand, static members belong to the class itself rather than instances. They are shared among all class instances and accessed using the class name. Static members often represent shared properties or behaviors not specific to individual instances.

Creating and using decorators

In this example, we’ll delve into a demonstration of TypeScript decorators and explore all four significant types of decorators.

Let’s dive into the code to see how these decorators can be effectively applied.

index.ts
tsconfig.json
// Parameter decorator
function logParameter(target: any, propertyKey: string, parameterIndex: number) {
console.log(`Parameter decorator called on ${propertyKey} parameter ${parameterIndex}`);
}
// Class decorator
function logClass(target: any) {
console.log(`Class decorator called on class: ${target.name}`);
}
// Method decorator
function logMethod(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
// Modify the method behavior
descriptor.value = function (...args: any[]) {
console.log(`Method decorator called on method: ${propertyKey}`);
const result = originalMethod.apply(this, args);
return result;
};
return descriptor;
}
// Property decorator
function logProperty(target: any, propertyKey: string) {
console.log(`Property decorator called on property: ${propertyKey}`);
}
@logClass
class Example {
@logProperty
message: string = "Hello, decorator!";
@logMethod
greet(@logParameter name: string) {
console.log(`Hello, ${name}!`);
}
}
const instance = new Example();
instance.greet("Learner");
All four types of decorators being applied

Explanation

Lines 2–4: We define the logParameter decorator. This decorator is intended to log information about the parameter it’s applied to when the decorated method is invoked.

Lines 6–9: We define the logClass decorator. This decorator logs a message indicating that the decorator has been called, and it displays the name of the class when it is defined.

Lines 12-20: We define the logMethod decorator. Inside this decorator, we store a reference to the original method of the decorated class in the originalMethod variable.

Lines 26–28: We define the logProperty decorator. This decorator logs a message when the decorated property is accessed.

Line 30: We apply the @logClass decorator to the Example class. This decorator logs a message when the class is defined, displaying the class name.

Lines 32–33: Inside the Example class, we define a property named message and apply the @logProperty decorator to it. This logs a message when the property is accessed.

Lines 35–38: We apply the @logMethod decorator to the declared greet method. This decorator modifies the behavior of the method by wrapping it with logging statements. Also, the @logParameter decorator is applied to the name parameter of the greet method. This logs a message when the parameter decorator is called on the decorated method.

Lines 41–42: We call the greet method of the instance object with the argument "Learner". This triggers the decorated method and its associated decorators, resulting in log messages being displayed in the console.

Note: Experiment by toggling experimentalDecorators to false in tsconfig.json and observe any changes in code behavior. Don’t forget to set it back to true for proper decorator functionality.

widget

Key use cases of decorators

Notably, widely used frameworks like Angular and NestJS leverage decorators extensively to streamline various aspects of component definition, dependency injection, and routing, underscoring their significance in modern web development.

Limitations of decorators

Decorators in TypeScript are powerful features, but it’s essential to be aware of their limitations. Decorators are currently an experimental feature in TypeScript, which means they might undergo changes or refinements in future versions of the language. As a result, there could be compatibility issues or variations in behavior between different TypeScript versions.

Furthermore, there are some specific limitations to consider. Decorators can only be applied to classes, methods, properties, or parameters. They cannot be directly applied to function expressions or arrow functions. Additionally, it’s worth noting that decorators cannot be used on function or class declarations.

Free Resources

Copyright ©2025 Educative, Inc. All rights reserved