4

TypeScript: view on playground

class A {
    protected _name: string = ""

    set name(name: string) {
        this._name = name
    }   
    get name() {
        return this._name
    }
}

class B extends A {
    protected _name: string = ""

    set name(name: string) {
        this._name = name + "B"
    }
}

In the compiled class B this will overwrite the definition of the set AND get:

Object.defineProperty(B.prototype, "name", {
    set: function (name) {
        this._name = name + "B";
    },
    enumerable: true,
    configurable: true
});

The result is, that get name does not work anymore on class B:

let b = new B()
b.name = "test"
console.log(b.name) // undefined

Is there a way to inherit the getter from class A?

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
CoderPi
  • 12,985
  • 4
  • 34
  • 62
  • 2
    Unfortunately it is the `name` that you are overriding, not the specific getter/setter. You could do `get name(){ return super.name; }` though. Would that be enough in your case? – loganfsmyth Dec 11 '15 at 18:40
  • possible duplicate of [Override a setter, and the getter must also be overridden](http://stackoverflow.com/q/28950760/1048572) – Bergi Dec 14 '15 at 18:39

1 Answers1

1

The below code works in the TypeScript compiler, without any errors:

class A {
   protected _name: string = ""

   set name(name: string) {
       this._name = name
   }   
   get name() {
       return this._name
   }
}

class B extends A {
   // Removed _name declaration here

   set name(name: string) {
       super["name"] = name + "B"      // <=== Using super here
   }
   get name() {
       return super["name"]            // <=== And here
   }
}

var b = new B();
b.name = "foo";
console.log(b.name); // "fooB"

The only difference from @Crowder's code is that instead of super.name I'm using super["name"]. If you use super.name the compiler will issue this error: Only public and protected methods of the base class are accessible via the 'super' keyword. Please note: TypeScript still compiles when it finds errors, so using super.name also works, notwithstanding the errors.

Marcelo Glasberg
  • 29,013
  • 23
  • 109
  • 133
  • Sounds like your `name` property in `A` was declared private by accident. There's no reason to use bracket notation for static property names, rather you should fix the reason of the compiler error (warning). – Bergi Feb 24 '16 at 22:16
  • @Bergi: `name` is not private. The compiler is complaining because only public and protected METHODS of the base class are accessible via the 'super' keyword, and `name` is not a METHOD. The bracket notation is, of course, only a hack, to bypass the compiler warning, since `super.name` also works. – Marcelo Glasberg Feb 25 '16 at 00:05
  • Have you tried reporting this as a bug to typescript? All properties, not only methods, should be available via `super`. – Bergi Feb 25 '16 at 00:26
  • I haven't. The error message is very clear that only methods are allowed, and it behaves like that, so I assumed it's the expected behavior. Can you tell me where it says all properties, not only methods, should be available via super? – Marcelo Glasberg Feb 25 '16 at 02:16
  • 1
    I don't know where or whether is says something, and what exactly. But it clearly should be changed, in the compiler and possibly in the spec if necessary. This hack should not be required to suppress this error. – Bergi Feb 25 '16 at 02:45
  • 1
    Thank you @MarcG, this should be the accepted answer : ) – Ignasi Oct 27 '16 at 23:48