'Uncaught TypeError: Illegal constructor when using HTMDivElement class in JS

[EDIT (2)] The following change gets rid of the error, but the element does not show up in the browser (however it appears in the 'inspector' (developer tools), see image hereunder):

// test.ts (amended version)


class MyElement extends HTMLElement implements HTMLDivElement {
    align: string;
    constructor() {
        super();
        this.align = "center";
    }
    public connectedCallback(): void {
        this.style.backgroundColor = "red";
    }
}

window.customElements.define('my-element', MyElement);

const myElement = document.createElement("my-element");
myElement.style.width = "100px";
myElement.style.height = "100px";
myElement.style.backgroundColor = "red";

// connectedCallback is called when appended to another element
document.body.appendChild(myElement);

enter image description here

  • I have tried to use the JS HTMLDivElement class with the code hereunder

  • Is it possible to subclass HTMLDivElement?

  • If not, then how does one create (and subclass) a div (or any other HTML element in TS (or JS))?

The command used to compile the TS into JS is:

tsc

tsc version: Version 4.6.2 / Node version: v17.4.0

(with the config file hereunder)

I get the error message (in all browsers dev tools) :

Uncaught TypeError: Illegal constructor.
    MyElement file:///Users/sergehulne/Documents/code/JS/axino2/test.js:3
    <anonymous> file:///Users/sergehulne/Documents/code/JS/axino2/test.js:11
test.js:3:9

// test.ts

class MyElement extends HTMLDivElement {
    constructor() {
        super();
    }
    public connectedCallback(): void {
        this.classList.add(`myElement`);
        this.style.backgroundColor = "red";
    }
}

customElements.define('my-element', MyElement);

const myElement = new MyElement();
// connectedCallback is called when appended to another element
document.body.appendChild(myElement);

// test.js

class MyElement extends HTMLDivElement {
    constructor() {
        super();
    }
    connectedCallback() {
        customElements.define('my-element', MyElement);
        this.classList.add(`myElement`);
        this.style.backgroundColor = "red";
    }
}
const myElement = new MyElement();
// connectedCallback is called when appended to another element
document.body.appendChild(myElement);

// tsconfig.json

{
  "compilerOptions": {
    "target": "es6"
  }
}

// index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script src="test.js"></script>
</body>
</html>


Solution 1:[1]

The following code seems to do the trick to some extents but, as mentioned in the comments, compiling from TS to JS via tsc seems to dump the :implements HTMLDivElement part of the initial test.ts class, as a consequence the width and height of the element are ignored.

The result looks like:

<div style="background-color: red;">My text!</div>

and not like

<div style="background-color: red; width: 100px; height: 100px;">my text!</div>
class MyElement extends HTMLElement implements HTMLDivElement {
    align: string;
    constructor() {
        super();
        this.align = "center";
    }
    public connectedCallback(): void {
        this.style.backgroundColor = "red";
        this.style.width = "100px";
        this.style.height = "100px";
    }
}

window.customElements.define('my-element', MyElement);

const myElement = document.createElement("my-element");
const Content = document.createTextNode("My text!");
myElement.appendChild(Content);
// connectedCallback is called when appended to another element
document.body.appendChild(myElement);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Serge Hulne