Decorators with TypeScript
All posts in TypeScript series:
- TypeScript – Union types, type guards and type aliases
- Intersection types in TypeScript
- Tuples in TypeScript
- Decorators with TypeScript
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:
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