Learning TypeScript 05 — Decorators

This feature is present in other languages as Attributes, Attribute Decorations or Decorators, and are going to be present in future EcmaScript versions.

Some years ago we used a similar pattern called Mixin but these two patterns have some differences. When you use a mixin you’re literally extending your class. A common example that we did in the past hundreds of times is to add a mixin to make your class be able to emit events.

But when you use a decorator, what you are doing is to encapsulate some functionality, without extending your class, and respecting the same structure that you have (example: implementing the same interface).

We have basically two types of decorators.

  • We can decorate a class: Decorating a class we are going to implement the changes to the whole class, receiving the constructor and modifying all that we want.

Imagine that we have a class that is called MyHero, and has two properties, name and strength, if we decorate the class as Archer we will obtain something like this:

Example of a class decorator

And if we change from Archer to Wizard:

Changing the class decorator

What we have is the “same” hero, with the same name and strength but looks totally different. Because the decorations are changing the class but respecting the core of our entity.

  • We can also decorate a property: And these changes are going to apply only to this property, receiving the target and the key of this property.

In the same example, we can decorate the name.

Example of property decorator

This new decorator if only adding ‘<<’ and ‘>>’ to the value of the property, this means that we can use on both of them without a problem.

Changing the property decorator

Nowadays, the common pattern is to use a decorator, probably because is cleaner to implement than a mixin, but usually we implement mixins inside decorators, a good example is Angular, when you use @injectable, @component you’re working with decorators but you could do that with mixins.

Luckily is not only in Angular, other frameworks like Vue or React are using (optionally) the power of decorators.

Let’s see an example of a Vue class with and without decorators.

On the left Vue component without decorators, on the right with decorators

And which is better? This will depend on your necessities haha 😇

If you know very well how Vue works, the left image will seem easier, and probably you are going to be faster creating this component.

But TypeScript, and in this case decorators, are not here to be faster.

  • If you come to this file in 3, 6 or 8 months the right side will be easier to understand in what you were thinking when you wrote that.
  • If another person has to read your code, and this person doesn’t know a lot about Vue, the right side will be easier to understand.
  • If the file starts to increase (and you are totally sure that has to increase) , the right side will be easier to understand.

In a few words, in this case, decorators are really nice when you’re searching for maintainability, scalability, and productivity in your code.

That doesn’t have to be always what you’re searching for. For example, if all you’re team is an expert in JavaScript and Vue you won’t need that, or if you’re creating a small website that will die in some months (like marketing websites).

And now.. let’s see how to create a decorator 🤩

I’ve created a simple class that receives a name in the constructor and shows this name in the DOM.

Example of simple class

We can easily create a decorator to capitalize the name, it’s only a function (could be useful to learn something about Reflect API).

Decorating a property

And also is not so difficult to decorate the whole class.

Example of class decorator

You can play with this example, and try to create more complex decorators.

You can find more info about this article in the official guide.
And info about why I’m doing this articles about TypeScript.
Let’s continue with the next chapter: Declaration files.
And remember, feedback is welcome 🤙.