yccteam
yccteam

Reputation: 2311

Typescript and custom elements properties compilation issue

I have this custom elements:

class CustomElement extends HTMLElement{
 constructor(){ super(); }
config: ConfigModel;
}
window.customElements.define('my-element', CustomElement);

Then, somewhere in the code, I have something like this:

const myElement = document.createElement('my-element');
myElement.config = config;

TS throws an error here: error TS2339: Property 'config' does not exist on type 'HTMLElement'.

Any idea how to solve this issue?

EDIT: It was suggested to cast the element's type. While this works, it does poses 2 problems:

  1. I don't necessarily want every service that uses the custom element to know about the custom element's class
  2. If I mock the custom element for tests, the hard coded custom element in the service won't allow mocking.

Here's the gist that explains it: https://gist.github.com/YonatanKra/de42be2fa5499157169ef141ba377998

Upvotes: 1

Views: 3143

Answers (2)

Mathyn
Mathyn

Reputation: 2620

You need to cast the element to the expected type since Typescript cannot know the type in this scenario.

const myElement = <CustomElement>document.createElement('my-element');

Also you need to inherit the HTMLElement class in your CustomElement:

class CustomElement extends HTMLElement {

Edited answer based on further questions:

Obviously if you ever want to access the properties of a CustomElement object you would need to type cast. However in all other cases you can just use the default HTMLElement type. It should still allow you to perform certain operations on the object, just not anything CustomElement related. So not every service needs to know it is a CustomElement object.

For mocking you could create a CustomElementMock class which inherits from CustomElement

class CustomElementMock extends CustomElement {
}

The mock version is still of type CustomElement and your original code should still accept it. However inside the mocked class you could overwrite all functionality to either do nothing or returned mocked data.

Upvotes: 2

Avin Kavish
Avin Kavish

Reputation: 8947

Use document.createElement('my-element') as CustomElement

Upvotes: 0

Related Questions