I am quite new to TypeScript and there is a point I do not quite understand.
Imagine the following classes:
export class PropertyInConstructor {
constructor(public foo: boolean) {
}
}
export class PropertyWithGetSet {
private _foo: boolean = false;
get foo(): boolean {
return this._foo;
}
set foo(theFoo: boolean) {
this._foo = theFoo;
}
}
From my understanding these two approaches both provide me a property that I can access using new PropertyInConstructor().foo
or new PropertyWithGetSet().foo
.
I now want to get the existing properties of such a class (without instance!) and to try it out:
console.log(Object.getOwnPropertyNames(PropertyInConstructor.prototype));
console.log(Object.getOwnPropertyNames(PropertyWithGetSet.prototype));
["constructor"]
["constructor", "foo"]
Why is it that the call where the properties are specified inside the constructor does not add the "foo" property?
Is there something missing or some other way to get those properties?
Short answer: most properties are added to the instance dynamically at runtime. Properties with getters and setters need to be added to the prototype with Object.defineProperty
.
With your first example:
export class PropertyInConstructor {
constructor(public foo: boolean) {
}
}
The property is only added to the instance when the constructor runs. Here is the transpiled JavaScript:
var PropertyInConstructor = /** @class */ (function () {
function PropertyInConstructor(foo) {
this.foo = foo;
}
return PropertyInConstructor;
}());
Effectively, the property foo
does not exist on the class until the constructor runs.
This isn't just for constructor properties, it is for all properties that are not defined against the prototype, for example:
class PropertyInConstructor {
public foo: boolean;
constructor() {
this.foo = true;
}
}
When you use get and set, things are different, because the property is added to the prototype:
var PropertyWithGetSet = /** @class */ (function () {
function PropertyWithGetSet() {
this._foo = false;
}
Object.defineProperty(PropertyWithGetSet.prototype, "foo", {
get: function () {
return this._foo;
},
set: function (theFoo) {
this._foo = theFoo;
},
enumerable: true,
configurable: true
});
return PropertyWithGetSet;
}());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With