TypeScript: Extending HTMLElement still not working

TypeScript Version: 2.1.4

Code

So the following JS works fine in Chrome (v55)

class MyCustomElement extends HTMLElement {
    constructor() {
        super();
        this.foo = "bar";
    }

    doSomething() {
        console.log(this.foo);
    }
}

customElements.define("my-custom-element", MyCustomElement);

Which of course can be represented with the following TypeScript:

class MyCustomElement extends HTMLElement {
    foo: string;
    constructor() {
        super();
        this.foo = "bar";
    }

    doSomething() {
        console.log(this.foo);
    }
}

customElements.define("my-custom-element", MyCustomElement);

Except the compiled typescript won’t run

tsc Output

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; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var MyCustomElement = (function (_super) {
    __extends(MyCustomElement, _super);
    function MyCustomElement() {
        var _this = _super.call(this) || this;
        _this.foo = "bar";
        return _this;
    }
    MyCustomElement.prototype.doSomething = function () {
        console.log(this.foo);
    };
    return MyCustomElement;
}(HTMLElement));
customElements.define("my-custom-element", MyCustomElement);

In Chrome’s console i see:

Uncaught TypeError: Failed to construct ‘HTMLElement’: Please use the ‘new’ operator, this DOM object constructor cannot be called as a function.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 5
  • Comments: 35 (2 by maintainers)

Most upvoted comments

ah I think you’re running into this issue https://github.com/webcomponents/custom-elements#known-issues

I also get that error.

Uncaught TypeError: Failed to construct 'HTMLElement': Please use the 'new' operator, this DOM object constructor cannot be called as a function

Yes, I suspected this is the issue. It’s really unfortunate that something like Reflect.construct wasn’t provided earlier on in runtimes.

For others running into this issue, I suggest using the shim that @robdodson linked to - thanks for the response Rob!

Of course. For reference, what our build system does is follow all imports to find every file and compile if necessary. You can use the polymer-build library to get gulp streams of all dependencies to process on your own.

No, Polymer is not compiled, because custom elements require ES6 classes. You have to distribute ES6 and compile everything at the app level if necessary for the environment.

We know about this issue for the polyfill, which is why we wrote the native-shim, which is now shipped as the custom-elements-es5-adapter. js.

We did have a race condition with the polyfill loader and native HTML imports that was causing this error to still occasionally occur, but that should be fixed by always including the adapter when serving compiled code.