Anik Ghosh
Anik Ghosh

Reputation: 63

Typescript property decorator - Need help to understand how the following happens?

I was just experimenting with Typescript property decorators. But, I could not understand the behavior of the following code :

function dec(hasRole: boolean) {
    return function (target: any, propertyName: string) {
        let val = target[propertyName];
        Object.defineProperty(target, propertyName, {
            get() { return val; },
            set(value) { val = hasRole; }
        });
    }
}

class Hey {
    age: number;

    @dec(true)
    hasRole: boolean = false;

    constructor(age: number) {
        this.age = age;
    }
}

let ob = new Hey(22);
console.log(ob);

//Actual Output:

age: 22
hasRole: true
__proto__:
  constructor: class Hey
  hasRole: true
  get hasRole: ƒ get()
  set hasRole: ƒ set(value)
  __proto__: Object

The result I expected was: 1. OwnProperty -> hasRole = false 2. Prototype property -> hasRole = true. As 'target' in decorator argument provides the constructor function for static members or prototype of the class for instance members.

Could someone explain me this functionality ?

Upvotes: 3

Views: 267

Answers (1)

yurzui
yurzui

Reputation: 214047

In order to understand it clearly you should take a look at the transpiled version

function dec(hasRole) {
    return function (target, propertyName) {
        let val = target[propertyName];
        Object.defineProperty(target, propertyName, {
            get() { return val; },
            set(value) { val = hasRole; }
        });
    };
}
class Hey {
    constructor(age) {
        this.hasRole = false;
        this.age = age;
    }
}
__decorate([
    dec(true)
], Hey.prototype, "hasRole", void 0);
let ob = new Hey(22);
console.log(ob);

From the code above it should be clear that class is decorated first and only then a new instance is created

It means that at the time constructor is being executed hasRole is already defined in Prototype hence assigning this.hasRole to anything doesn't have any effect: it's always assigned to hasRole parameter in decorator(which is true)

Upvotes: 2

Related Questions