TypeScript Decorators
An introduction to decorator in Typescript; A resemblance to Angular component decorator.
Prologue
It's known that Angular internally uses "Decorators" intensively. Moreover, NgRX and NGXS, a more elegant library, both provide a set of handy and reusable decorators to help application composition. The concept of “Decorators” is not restricted in the world of TypeScript or Angular. “Decorators” is applicable to all JS frameworks, such as in VueJS (vue-class-component, vue-property-decorator, …) and React/Redux (mobx-react, react-redux, redux-form, react-dnd …).
“Decorators” is currently in ECMAScript Proposals Stage-2. And TC39 will discuss the possibility of promoting “Decorators” to Stage-3 in July 2018. The specs for “Decorators” might remain the same or might change. Anyhow, JavaScript community has already built up many “Decorator” libraries with significant amounts of downloads, such as core-decorators, lodash-decorators, and babel-plugin-syntax-decorators.
Back to our FBIS environment, I haven’t found any needs of writing a customized “Decorator” so far. However, having some basic knowledge of “Decorators” would help us reading/understanding libraries/frameworks using “Decorators”.
Decorator Examples
- readonly
- log
- time
- notnull
- deprecated
- serializable
- serialize
- memoize
- component
- event
- component-with-interpolation
Decorators Concepts
A Decorator is a special kind of declaration that can be attached to a class declaration, method, accessor, property, or parameter.
Evaluation Order
- Parameter Decorators, followed by Method, Accessor, or Property Decorators are applied for each instance member.
- Parameter Decorators, followed by Method, Accessor, or Property Decorators are applied for each static member.
- Parameter Decorators are applied for the constructor.
- Class Decorators are applied for the class.
Decorator Composition
@f @g x
// or
@f
@g
x
In this model, when composing functions f and g, the resulting composite (f ∘ g)(x) is equivalent to f(g(x)).
Class Decorators
function ClassDecorator(
target: any // The class the decorator is declared on
) {}
@ClassDecorator
class ClassDecoratorExample {}
Method Decorators
function MethodDecorator(
target: any, //Either the constructor function of the class for a static
//member, or the prototype of the class for an instance member.
propertyKey: string, // The name of the member.
descriptor: PropertyDescriptor //The Property Descriptor for the member.
) {}
class ClassExample {
@MethodDecorator
method(){}
}
Accessor Decorators
Function signature is the same as Method Decorators
Property Decorators
function PropertyDecorator(
target: any, //Either the constructor function of the class for a static
//member, or the prototype of the class for an instance member.
propertyKey: string // The name of the member.
) {}
class ClassExample {
@PropertyDecorator
prop: string;
}
Parameter Decorators
function ParameterDecorator(
target: any, //Either the constructor function of the class for a static
//member, or the prototype of the class for an instance member.
propertyKey: string // The name of the member.
index: number //The ordinal index of the parameter in the function’s parameter list.
) {}
class ClassExample {
method(@Parameterecorator param1: string){}
}