Skip to content
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

Specifying a get xor set property in a subclass silently invalidates parent class's property accessor #13669

Closed
irfaanc opened this issue Jan 25, 2017 · 3 comments
Labels
Duplicate An existing issue was already created

Comments

@irfaanc
Copy link

irfaanc commented Jan 25, 2017

TypeScript Version: 2.1.1

Code

class Read
{
  protected _x: number = 123;

  get x(): number
  {
    return this._x;
  }
}

class ReadWrite extends Read
{
  set x(value: number)
  {
    this._x = value;
    return;
  }
}


let read = new Read();
let write = new ReadWrite();

console.log(read.x);  // 123
console.log(write.x); // expected: 123. Actual: undefined

Expected behavior:

Either ReadWrite should properly inherit the x get accessor from Read, or the compiler should throw an error.

Actual behavior:

The code compiles without error or warning, but the subclass ReadWrite doesn't keep the parent class's get accessor for x.

ReadWrite's "definition" code's in the output JS calls Object.defineProperty, but since it only directly mentions the setter, the parent's get accessor is lost. And, obviously, the reverse case is also true - defining setter in a base class will become undefined if a subclass defines a getter.

I'd prefer if ReadWrite properly inherited the getter. But I realize that'd requires adding code to trolling through a class's prototype chain to retrieve any existing get and set values to propagate forward.

If this isn't deemed important enough to correct, could the compiler at least spit out a warning or error? A close analogy would be error TS2415, which gets thrown if a subclass attempts to override a private member of a parent class that happens to share the same name.

@HerringtonDarkholme
Copy link
Contributor

This works as intended. Paste the equivalent code in node. The output is in par with tsc and babel.

class Read
{
  constructor() {
    this._x = 123
  }
  get x()
  {
    return this._x;
  }
}

class ReadWrite extends Read
{
  set x(value)
  {
    this._x = value;
    return;
  }
}


let read = new Read();
let write = new ReadWrite();

console.log(read.x);  // 123
console.log(write.x); // nodejs: undefined

Otherwise, #11596 will prohibit write-only accessors.

@RyanCavanaugh
Copy link
Member

See #13432

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Jan 25, 2017
@irfaanc
Copy link
Author

irfaanc commented Jan 25, 2017

@RyanCavanaugh
I don't entirely agree with the Duplicate classification. Bug #13432 mentions the compiler is throwing an error message. The case I present does not generate a compiler error. Which is why I opted to even file this issue, after it cost me a silly amount of time. I read #13432 too quickly; I misread the runtime error (which does not trigger in the case I present) as a compile time error.

@HerringtonDarkholme
I'm not sure what bug #11596 or babel's relationship is to this undesirable behavior. My concern isn't creating a write-only accessor. My concern is unexpected behavior that isn't inline with how the rest of inheritance behaves in typescript, or any other language with a similar inheritance scheme. Nothing in the typescript language spec nor documentation even hints this is a Bad Thing to do.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

3 participants