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

Opting out for super call requirement? #9503

Closed
saschanaz opened this issue Jul 4, 2016 · 6 comments
Closed

Opting out for super call requirement? #9503

saschanaz opened this issue Jul 4, 2016 · 6 comments
Labels
Duplicate An existing issue was already created

Comments

@saschanaz
Copy link
Contributor

saschanaz commented Jul 4, 2016

TypeScript Version: master branch

Code

class EVE extends HTMLElement {
  constructor() {
    return document.createElement("sn-eve"); // Error
  }
}

let eve: EVE;
eve = document.createElement("sn-eve"); // No error

Expected behavior:
It should work if a constructor function return an object which is structurally compatible with the declared class.

Actual behavior:
Error: Constructors for derived classes must contain a 'super' call.

Workaround:

class EVE extends HTMLElement {
  constructor() {
    if ({} === undefined) {
      super();
    }
    return document.createElement("sn-eve");
  }
}
@kitsonk
Copy link
Contributor

kitsonk commented Jul 4, 2016

In plain JavaScript:

class EVE extends HTMLElement {
  constructor() {
    super(); // TypeError: Illegal Constructor
    return document.createElement("sn-eve");
  }
}

let eve1 = new EVE();

let eve2 = document.createElement("sn-eve");

So not only is it "unwanted", if super() is called, it will throw, so TypeScript is requiring invalid ES6 syntax.

@MattiasBuelens
Copy link
Contributor

MattiasBuelens commented Jul 4, 2016

What's the point of making EVE a class when you cannot add methods or properties to it, or even extend it? It is not sufficient for a class constructor to create an object that is structurally compatible with the class's interface. At a minimum, the class's prototype must be in the prototype chain of the constructed object, i.e. eve instanceof EVE should be true.

@saschanaz
Copy link
Contributor Author

saschanaz commented Jul 4, 2016

@MattiasBuelens I can:

class EVE extends HTMLElement {
  constructor() {
    if ({} === undefined) {
      super();
    }
    const tempThis = document.createElement("sn-eve");
    Object.setPrototypeOf(tempThis, EVE.prototype);
    return tempThis;
  }
  eve() {
    return 3;
  }
}

console.log(new EVE().eve()) // 3
console.log(new EVE() instanceof EVE) // true

@MattiasBuelens
Copy link
Contributor

MattiasBuelens commented Jul 4, 2016

@saschanaz Okay, I guess that works. What about a subclass of EVE that needs to call the super constructor, and then do some other things in its own constructor? How would this work:

class DerivedEVE extends EVE {
    constructor() {
        super();
        this.foo = "bar";
    }
}

I mean sure, you can probably find some roundabout way to make this refer to the return value of the super constructor. But really: would you still describe EVE as being a class at that point? Can it be used as a class everywhere?

I just don't see the value of being able to not call super() from a constructor for regular ES6-style classes. As for your use case of custom elements: unfortunately it's not as simple as creating an element and messing with its prototype (for example, would you expect <sn-eve> to work in HTML code?) The spec for custom elements is still being worked on and it'll probably use ES6 classes in some way, but there's more to it.

@saschanaz
Copy link
Contributor Author

saschanaz commented Jul 5, 2016

<sn-eve> will work as `HTMLUnknownElement on HTML code, and I can freely style it and append any child nodes to serve my purpose. Subclassing it unfortunately requires the same prototype hack.

I have to admit that it's not simple but it still is ES6, and if TypeScript still wants to require super() then it should do on TSLint not on the compiler.

@DanielRosenwasser
Copy link
Member

I think that this a duplicate of #7285, so I'll redirect the convo to there.

@DanielRosenwasser DanielRosenwasser added the Duplicate An existing issue was already created label Jul 5, 2016
@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
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

4 participants