Skip to content

Call base class property via super #4465

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wgebczyk opened this issue Aug 26, 2015 · 12 comments
Closed

Call base class property via super #4465

wgebczyk opened this issue Aug 26, 2015 · 12 comments
Labels
Bug A bug in TypeScript Fixed A PR has been merged for this issue Spec Issues related to the TypeScript language specification

Comments

@wgebczyk
Copy link

In following code:

class MyBase {
  getValue(): number { return 1; }
  get value(): number { return 1; }
}

class MyDerived extends MyBase {
  constructor() {
    super();

    const f1 = super.getValue();
    const f2 = super.value;
  }
}

var d = new MyDerived();
var f3 = d.value;

disallowing the line "const f2 = super.value;" to be valid is... plain stupid.
What is the scenario where this behavior is valid?

@zpdDG4gta8XKpMCd
Copy link

super is referring to the prototype object of a super class, not to the instance object, the instance object is shared between both super and sub classes, hence the limitation

@wgebczyk
Copy link
Author

IF "super is referring to the prototype object" THEN
"super.getValue()" would not work as do not have instance reference "this".

class MyBase {
  private _value: number;
  constructor(value: number) { this._value = value; }

  getValue(): number { return this._value; }
  get value(): number { return this._value; }
}

class MyDerived extends MyBase {
  constructor() {
    super(2);

    const f1 = super.getValue();
    const f2 = super.value;
    alert(`${f1} | ${f2} | ${MyBase.prototype.value}`);
  }
}

var d = new MyDerived();
var f3 = d.value;

alert gets "2 | undefined | undefined". This means super DOES NOT represent prototype, but instance (kind of parent instance, but still instance).

IF "super is referring to the base object instance" THEN
Why "super.value" does not work.

@zpdDG4gta8XKpMCd
Copy link

IF "super is referring to the prototype object" THEN

"...super is referring to the prototype object of a super class"

class MyBase {
  getValue(): number { return 1; }
  get value(): number { return 1; }
}

class MyDerived extends MyBase {
  constructor() {
    super();

    const f1 = super.getValue();
    const f2 = super.value;
  }
}

var d = new MyDerived();
var f3 = d.value;

is compiled to:

var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
};
var MyBase = (function () {
    function MyBase() {
    }
    MyBase.prototype.getValue = function () { return 1; };
    Object.defineProperty(MyBase.prototype, "value", {
        get: function () { return 1; },
        enumerable: true,
        configurable: true
    });
    return MyBase;
})();
var MyDerived = (function (_super) {
    __extends(MyDerived, _super);
    function MyDerived() {
        _super.call(this);
        var f1 = _super.prototype.getValue.call(this);
        var f2 = _super.prototype.value;
    }
    return MyDerived;
})(MyBase);
var d = new MyDerived();
var f3 = d.value;

Look over here: live example

@zpdDG4gta8XKpMCd
Copy link

missed your point, value is a property accessor not just a property, your original complaint looks valid

(everything that i said is still valid too :) )

@RyanCavanaugh
Copy link
Member

See #338

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Aug 26, 2015
@wgebczyk
Copy link
Author

Please do not close this as I'm targeting ES6.
Is there anything in ES2015 that prevents from using super.(base class field/property)?

@RyanCavanaugh RyanCavanaugh reopened this Aug 26, 2015
@RyanCavanaugh
Copy link
Member

Good point - we should at least allow this in ES6

@RyanCavanaugh RyanCavanaugh added Bug A bug in TypeScript Spec Issues related to the TypeScript language specification and removed Duplicate An existing issue was already created labels Aug 26, 2015
@wgebczyk
Copy link
Author

Thanks!

@vladima
Copy link
Contributor

vladima commented Dec 11, 2015

#5860 lifts the restriction for ES6, we still need a separate proposal for the downlevel emit

@vladima vladima closed this as completed Dec 11, 2015
@vladima vladima added the Fixed A PR has been merged for this issue label Dec 11, 2015
@tbebekis
Copy link

tbebekis commented Jun 30, 2017

var GetPropertyDescriptor = function (o, PropName) {
    if (o !== null) {
        return o.hasOwnProperty(PropName) ?
              Object.getOwnPropertyDescriptor(o, PropName) :
             GetPropertyDescriptor(Object.getPrototypeOf(o), PropName);
    }

    return null;
};

return GetPropertyDescriptor(base, 'Name').get.call(this); // getter call
GetPropertyDescriptor(base, 'Name').set.call(this, v); // setter call

The above works in plain javascript. It looks really ugly. Typescript would make it look a little nicer, perhaps using the super keyword.

@jsep
Copy link

jsep commented Jan 24, 2018

Maybe a bit late, but I was able to access super.<getter/setter> using bracket notation. super['value'].

I wanted to override a getter of my super, for example:

class Base {
    get value() {
        return 'a'
    }
}

class CustomBase extends Base {
    get value() {
        return super['value'] + 'b';
    }

}

@thw0rted
Copy link

thw0rted commented May 1, 2018

@jsep this is very helpful, do you have any idea why the index operator is allowed but calling super.value directly is an error?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Bug A bug in TypeScript Fixed A PR has been merged for this issue Spec Issues related to the TypeScript language specification
Projects
None yet
Development

No branches or pull requests

9 participants