镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Call base class property via super #4465

Description

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?

Activity

  1. zpdDG4gta8XKpMCd commented on Aug 26, 2015

    @zpdDG4gta8XKpMCd

    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

  2. wgebczyk commented on Aug 26, 2015

    @wgebczyk
    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.

  3. zpdDG4gta8XKpMCd commented on Aug 26, 2015

    @zpdDG4gta8XKpMCd

    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

  4. zpdDG4gta8XKpMCd commented on Aug 26, 2015

    @zpdDG4gta8XKpMCd

    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 :) )

  5. RyanCavanaugh commented on Aug 26, 2015

    @RyanCavanaugh
    Member

    See #338

  6. wgebczyk commented on Aug 26, 2015

    @wgebczyk
    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)?

  7. RyanCavanaugh commented on Aug 26, 2015

    @RyanCavanaugh
    Member

    Good point - we should at least allow this in ES6

  8. added
    BugA bug in TypeScript
    SpecIssues related to the TypeScript language specification
    and removed
    DuplicateAn existing issue was already created
    on Aug 26, 2015
  9. wgebczyk commented on Aug 26, 2015

    @wgebczyk
    Author

    Thanks!

  10. vladima commented on Dec 11, 2015

    @vladima
    Contributor

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

  11. tbebekis commented on Jun 30, 2017

    @tbebekis
    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.

  12. jsep commented on Jan 24, 2018

    @jsep

    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';
        }
    
    }
  13. thw0rted commented on May 1, 2018

    @thw0rted

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

  14. locked and limited conversation to collaborators on Jul 31, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScriptFixedA PR has been merged for this issueSpecIssues related to the TypeScript language specification

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions