Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

when are typescript/js decorators executed

When do decorators get executed?

class Person {
    @SomeDecorator
    age
}
  1. When I create an instance of Person
  2. When the Person class is parsed

What about static properties?

like image 412
Chris Avatar asked Nov 28 '17 20:11

Chris


People also ask

How does decorator work in TypeScript?

A Decorator is a special kind of declaration that can be attached to a class declaration, method, accessor, property, or parameter. Decorators use the form @expression , where expression must evaluate to a function that will be called at runtime with information about the decorated declaration.

Where can TypeScript decorators be applied to?

A Decorator is a special kind of declaration that can be applied to classes, methods, accessor, property, or parameter.

How do JavaScript decorators work?

Decorators are the way of wrapping one piece of code with another or apply a wrapper around a function in JavaScript. Decorators are the design pattern that allows behavior to be added to an individual object, either statically or dynamically without affecting the behavior of other objects from the same class.

How many decorators can be applied to a declaration in TypeScript?

There are five ways to use decorators and we will look at examples of each one.


1 Answers

A property decorator executes early - when the class is defined. You don't need to construct an instance, or access the property.

Example: this logs age without the Person class even being constructed. The same applies if the property is static.

function SomeDecorator(a, b) {
    console.log(b);
}

class Person {
    @SomeDecorator
    public age: number;
}

If you are after hooking into the get and set actions on the property - that is possible too. Here is an example from a listing in Pro TypeScript (Second Edition). It works by wrapping the getter and setter.

function log(target: any, key: string) {
    let value = target[key];

    // Replacement getter
    const getter = function () {
        console.log(`Getter for ${key} returned ${value}`);
        return value;
    };

    // Replacement setter
    const setter = function (newVal) {
        console.log(`Set ${key} to ${newVal}`);
        value = newVal;
    };

    // Replace the property
    if (delete this[key]) {
        Object.defineProperty(target, key, {
            get: getter,
            set: setter,
            enumerable: true,
            configurable: true
        });
    }
}

class Calculator {
    @log
    public num: number;

    square() {
        return this.num * this.num;
    }
}

console.log('Construct');
const calc = new Calculator();

console.log('Set');
// Set num to 4
calc.num = 4;

console.log('Get');
// Getter for num returned 4
// Getter for num returned 4
calc.square();

The output of this listing is:

Construct (manual log)

Set (manual log)

-> Set num to 4

Get (manual log)

-> Getter for num returned 4

-> Getter for num returned 4
like image 77
Fenton Avatar answered Oct 20 '22 03:10

Fenton