DEV Community

Cover image for Decorators in typescript
Marwa Abdelaal
Marwa Abdelaal

Posted on

Decorators in typescript

Typescript is a superset of Javascript. Typescript allows Javascript developers to add static type-checking and other modern features to plain Javascript. Some of these extra features do get added to the standard Javascript(ECMAScript).

The concept of Decorators is one of those extra features. In this article, we would see what Decorators are and how they can be used in Typescript.

What are Decorators?

Decorators are a feature in TypeScript that allow you to modify the behavior of classes, methods, properties, and other members at design time. Decorators are implemented as functions that can be attached to declarations using the @ symbol.

What are Decorators used for?

They can be used for a wide range of tasks, such as:

  • Adding additional behavior to a class or its members.
  • Implementing dependency injection.
  • Modifying third-party libraries without having to change the implementation of the library itself.

Getting started

To use decorators, you have to set the experimentalDecorators compiler to true option in the tsconfig.json file.

{
"compilerOptions": {
    "target": "ES5",
    "experimentalDecorators": true,
    }
}
Enter fullscreen mode Exit fullscreen mode

After setting up your project to use decorators, let's get coding!

Types of Decorators

Class Decorators

Class decorators are used to modify the behavior of a class at design time. They can be applied to the class declaration itself, and can also be used to modify the constructor function of the class.

Here is an example of a class decorator that adds a new method to a class:

function addMethod(target: any) {
  target.prototype.greet = function() {
    console.log("Hello, world!");
  };
}

@addMethod
class Greeter {
  name: string;

  constructor(name: string) {
    this.name = name;
  }
}

const greeter = new Greeter("Alice");
greeter.greet(); // logs "Hello, world!"

Enter fullscreen mode Exit fullscreen mode

In this example, we define a class decorator called addMethod that takes one argument, the target object (which is the constructor function of the class). The decorator adds a new method called greet to the prototype of the target object.

We then apply the addMethod decorator to the Greeter class using the @ symbol. When we create a new instance of Greeter and call the greet method, the decorator intercepts the call and executes the new method that we added to the class.

Property Decorators

Property decorators are used to modify the behavior of a class property at design time. They can be applied to the property declaration itself, and can also be used to modify the descriptor object that describes the property's properties.

The property decorator receives two arguments.

  • The prototype of the class for an instance member OR the constructor function of the class for a static member.
  • The name of the property.

Here's an example of a property decorator:

function readonly(target: any, propertyKey: string) {
  Object.defineProperty(target, propertyKey, { writable: false });
}

class MyClass {
  @readonly
  myProperty: string;
}

const myObject = new MyClass();
myObject.myProperty = "new value"; // throws a TypeError
Enter fullscreen mode Exit fullscreen mode

In this example, we define a property decorator called readonly that sets the writable property of the target property descriptor to false. We then apply the decorator to the myProperty property of the MyClass class using the @ symbol. Also Property decorators can be used to override the property being decorated. This can be done with the static method Object.defineProperty.

Decorators are just a clean syntax for wrapping a piece of code with a function

Are there any downsides?

While decorators are a powerful tool for adding functionality to classes, properties, and methods in TypeScript, there are some downsides to consider:

  1. Increased Complexity: Decorators can make the code more complex, especially if decorators are heavily used or if there are many decorators applied to a single property or method. This can make it harder to understand the behavior of the code, especially for developers who are not familiar with the decorator syntax.

  2. Debugging: Debugging code that uses decorators can be more difficult because the decorator code is executed at runtime, which can make it harder to trace the flow of execution and find errors.

  3. Limited Browser Support: While TypeScript supports decorators, they are not natively supported by all browsers. If you are targeting a browser that does not support decorators, you will need to use a transpiler like Babel to convert the decorator syntax to code that is compatible with that browser.

  4. Performance: Using decorators can impact the performance of the application, especially if many decorators are used. The extra overhead of decorator code can slow down the execution of the application, especially on slower devices or when dealing with large amounts of data.

It's important to consider these downsides when deciding whether to use decorators in your TypeScript code. While decorators can be a useful tool for adding functionality to your code, they should be used judiciously and only when the benefits outweigh the costs.

Conclusion

At this point I hope you had a good understanding of decorators, how they work and when to use them or avoid using them. In this article I covered only two types of decorators, however, there’s much more to learn. Decorators in Typescript can be applied not only to classes and methods, but also to properties of classes, and method arguments. I hope that with your newly acquired understanding of decorators you’ll be able to pick it up easily from the documentation.

If you’ve enjoyed this article feel free to clap for it so more people will find it and enjoy it as well, and if you wish to see more of the stuff I write you’re welcome to follow me. Let me know in the comments if you have any questions.
Thanks for reading!

Latest comments (1)

Collapse
 
emanuelgustafzon profile image
Emanuel Gustafzon

Thanks, so easy actually, but as we add methods to the prototype does this mean that children classes get affected?