Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript getter returns undefined although the private property is set

I've tried this code with TypeScript 2.6 and 3.4:

abstract class Base {
    private _prop = false;
    public get prop() { return this._prop; }
    public setProp(v) { this._prop = v; }

    private _otherProp = false;
    public get otherProp() { return this._otherProp; }
    public set otherProp(v) { this.setOtherProp(v); }    
    public setOtherProp(v) { this._otherProp = v; }
}

class MyBase extends Base {
    public set prop(v) { this.setProp(v); }
}

const base = new MyBase();

base.setProp(true);
base.setOtherProp(true);

console.log(`prop = ${base.prop}`); // prop = undefined
console.log(`otherProp = ${base.otherProp}`); // otherProp = true

Why the different result? Note that if I comment out the set prop() in the MyBase class then both properties return true, however this setter is never even executed, so why does it matter that it's there?

Run the code yourself (results in the console)

like image 636
BeetleJuice Avatar asked Nov 06 '22 16:11

BeetleJuice


1 Answers

You can't override just the set of a property, you are overriding the whole property it's just that you leave get undefined. get/set syntax is just syntactic sugar for Object.defineProperty which overrides the whole property.

Override get, and call super.prop and it all works as expected:

abstract class Base {
    private _prop = false;
    public get prop() { return this._prop; }
    public setProp(v: boolean) { this._prop = v; }

    private _otherProp = false;
    public get otherProp() { return this._otherProp; }
    public set otherProp(v) { this.setOtherProp(v); }    
    public setOtherProp(v: boolean) { this._otherProp = v; }
}

class MyBase extends Base {

    public get prop() { return super.prop; }
    public set prop(v: boolean) { this.setProp(v); }
}

const base = new MyBase();

base.setProp(true);
base.setOtherProp(true);

console.log(`prop = ${base.prop}`); // prop = true
console.log(`otherProp = ${base.otherProp}`); // otherProp = true

Playground link

like image 165
Titian Cernicova-Dragomir Avatar answered Nov 15 '22 11:11

Titian Cernicova-Dragomir