diff --git a/src/SUMMARY.md b/src/SUMMARY.md index d2bf9df..c94340f 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -18,6 +18,7 @@ - [arrays](./dev/ruby/arrays.md) - [TypeScript](./dev/ts/main.md) - [interfaces](./dev/ts/interfaces.md) + - [decorators](./dev/ts/decorators.md) - [JavaScript](./dev/js/main.md) - [ES6](./dev/js/es6.md) - [Web](./dev/web/main.md) diff --git a/src/dev/ts/decorators.md b/src/dev/ts/decorators.md new file mode 100644 index 0000000..f209237 --- /dev/null +++ b/src/dev/ts/decorators.md @@ -0,0 +1,93 @@ +# Decorators in TypeScript + +## Overview + +Decorators are an experimental feature of TypeScript (and also a JavaScript +stage 2 feature, meaning they will be soon included in standard JS) allowing +you to inject specific behaviors to classes, properties, methods, accessors +or parameters. + +This features allow some kind of meta-programming and dependency injection, +called at runtime. + +This is mainly used in libs to add specific behaviors to your own code. + +For example, [TypeORM](https://typeorm.io/), an ORM lib, use this feature to give a nice way for +users to annotate their models, the dedicated char to use decorator is `@` : + +```typescript +@Entity() +export class Person { + + @PrimaryGeneratedColumn() + id: number; + + @Column() + lastname: string; + +} +``` + +## Example + +This features needs to be explicitly set as enabled in your `tsconfig.json` : + +```json + "experimentalDecorators": true +``` + +Decorators are just functions, for example, here is a property decorator + +```typescript +class Decorator { + + // Call to the emoji decorator with a string passed as argument + @emoji("🦍") + name: string = ""; + + constructor(name: string) { + this.name = name; + } + +} + +// The actual decorator code, this is, in fact a decorator factory +// It's a high order function returning the actual decorator +// It's a common and nice way to have access to a larger scope to +// play with the args passed as params (emojo, here) +function emoji(emojo: string) { + // Return the actual decorator + return function (target: any, key: string) { + + // get the actual value + let val = target[key]; + + // customize getter + const getter = () => { + return val; + } + + // and setter, to add some nice emojos + const setter = (next: string) => { + val = ${emojo} ${next} ${emojo}; + } + + // Apply thoose changes to the actual object property + Object.defineProperty(target, key, { + get: getter, + set: setter, + enumerable: true, + configurable: true + }); + } +} + +const example = new Decorator("hello"); + +console.log(example.name); +``` + +Even if this example is quite useless, it gives an overview of the +possibilities of this feature. + +More ressources can be found in the [Handbook](https://www.typescriptlang.org/docs/handbook/decorators.html)