Decorators

Decorators are proposed for a future version of JavaScript, but the Angular team really wanted to use them, and they have been included in TypeScript.

Decorators are functions that are invoked with a prefixed @ symbol, and immediately followed by a class, parameter, method or property. The decorator function is supplied information about the class, parameter or method, and the decorator function returns something in its place, or manipulates its target in some way. Typically the "something" a decorator returns is the same thing that was passed in, but it has been augmented in some way.

Decorators are quite new in TypeScript, and most use cases demonstrate the use of existing decorators. However, decorators are just functions, and are easier to reason about after walking through a few examples.

Decorators are functions, and there are four things (class, parameter, method and property) that can be decorated; consequently there are four different function signatures for decorators:

  • class: declare type ClassDecorator = <TFunction extends Function>(target: TFunction) => TFunction | void;

  • property: declare type PropertyDecorator = (target: Object, propertyKey: string | symbol) => void;

  • method: declare type MethodDecorator = <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void;

  • parameter: declare type ParameterDecorator = (target: Object, propertyKey: string | symbol, parameterIndex: number) => void;

Readers who have played with Angular will notice that these signatures do not look like the signatures used by Angular specific decorators like @Component().

Notice the () on @Component. This means that the @Component is called once JavaScript encounters @Component(). In turn, this means that there must be a Component function somewhere that returns a function matching one of the decorator signatures outlined above. This is an example of the decorator factory pattern.

If decorators still look confusing, perhaps some examples will clear things up.