Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Property {created in html element} does not exist on type 'HTMLElement'

In typescript, an html element is typed with HTMLElement. But what if I add a property to that HTML element, the HTMLElement type will fail. How can I type an html element with a new property. Here is the code where I get the error:

function divModify():HTMLElement{
  const div:HTMLElement= document.createElement("div");
  div.id= "test";
  div.classList.add("d-flex");
  const info={text: "Hello word"}
  Object.defineProperty(div,"info",{value:info})
  console.log(div)
  console.log(div.info)
  return div
}

divModify()

the error:

Property ‘info’ does not exist on type ‘HTMLElement’.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

and a playground of the code: code playground

>Solution :

While TypeScript’s flow-analyzer is very impressive and allows for types to be refined, narrowed, or widened within a scope when you use type-guard type predicate functions, typeof and instanceof, TypeScript still doesn’t yet track all changes to a variable’s type which should otherwise be inferable from use of the in operator or Object.defineProperty.

(UPDATE: So TypeScript 4+ does use in for narrowing, but only to discriminate between possibilities in union types)

so until TypeScript supports following Object.defineProperty you can workaround that limitation with some manual tweaks:

  • Manually defining a new type that combines the DOM’s built-in HTMLDivElement type with a singular info: { readonly text: string } type.

    • My code below also defines info‘s Type as type MyInfo instead of being anonymous.
    • I call this HTMLDivElementWithInfo.
  • Change the divModify function to return HTMLDivElementWithInfo instead of HTMLDivElement.

  • Add a type-assertion to Object.defineProperty‘s return-value (which is an alias of div) named div2 as HTMLDivElementWithInfo.

  • After all that, tsc will now allow you to dereference div.info.

Like so:

Playground link.

type MyInfo                 = { readonly text: string; };
type HTMLDivElementWithInfo = HTMLDivElement & { info: MyInfo };

function createDivWithInfo(): HTMLDivElementWithInfo {

  const div = document.createElement("div");
  div.id = "test";
  div.classList.add("d-flex");

  const initialInfoPropValue = { text: "Hello word" };
  const div2 = Object.defineProperty( div, "info", { value: initialInfoPropValue } ) as HTMLDivElementWithInfo;

  console.log( div2 );
  console.log( div2.info );
  return div2;
}

const d = createDivWithInfo();
console.log( d.info );
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading