Reputation: 63
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
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