Decorators with TypeScript

This entry is part 4 of 4 in the TypeScript series

Introduction

JavaScript decorators are a special kind of declaration. Decorators can be attached to both class declaration and class method declaration. Furthermore, they can be attached to accessor and property declaration. Finally, they can also be attached to parameter declaration.

If you come from backend world and you have worked with C# or Java you probably used something similar. They remind of attributes in C# or annotations in Java. While they have similarities, they are not exactly the same thing. In JavaScript they are not only metadata. They represent declarative way of adding properties and behavior to prototypes, constructors or even object functions.

When applying decorators to declaration we use the form @functionName, where functionName represents a function. That means that in JavaScript decorators are implemented in form of functions. Those functions will be called at runtime.

It is especially relevant to emphasize that decorators are proposed feature for future version of JavaScript. They are currently in stage 2 proposal for ECMAScript. Hence, they are an experimental feature in TypeScript which needs to be enabled via tsconfig.json:

{
    "compilerOptions": {
        "target": "ES5",
        "experimentalDecorators": true
    }
}
 

or via parameters through tsc CLI.

tsc --target ES5 --experimentalDecorators

 

Decorators example

Simple method decorator:

 

target parameter is either constructor function or the prototype of the class for an instance member, propertyKey is the name of the method, descriptor is the property descriptor.

As a result of executing previous code we get the following output:

console output

Decorator Composition

You can assign multiple decorators to a declaration:

 

Here is the output:

a(): evaluated
b(): evaluated
c(): evaluated
c(): called
b(): called
a(): called

As you can see, expressions for decorators are applied from top to bottom, while results are called as functions in reverse order – from bottom to top. It is important to notice that we got the output here without making an instance of Test class and calling the method appendTextToName explicitly. That is because our decorator functions (a, b, c ) are executed at runtime.

 

Summary

Lets sum up what we have learned about decorators so far:

  • Proposed feature for future version of JS
  • Declarative programming
  • They are functions
  • You can apply multiple decorators to a declaration
  • You can apply them to:
    • classes
    • methods
    • properties
    • accessors
    • parameters

 

You can find the code at https://github.com/Ibro/typescript-decorators



TypeScript Series Navigation: Previous post: << Tuples in TypeScript
Next post:



Ibrahim Šuta

Software Consultant interested and specialising in ASP.NET Core, C#, JavaScript, Angular, React.js.