javascripttypescriptdomvisual-studio-codeclonenode

Property 'id' does not exist on type 'Node' in plain JS after cloneNode


I've got a pure JS function that adds a message to the page based on a chunk of "template" HTML.

const setMessage = (msg, type, msg_ct) => {
    const msg_text = document.createTextNode(msg)
    const elementToCopy = document.querySelector('#js_message_template')
    const msg_container = document.querySelector('#js_message_container')
    const clone = elementToCopy.cloneNode(true)

    clone.id = `js_message_alert_${msg_ct}`
    clone.classList.add(`alert-${type}`)
    clone.appendChild(msg_text)
    msg_container.appendChild(clone);   
}

VS code is complaining about clone.id and clone.classList as a Node cannot have those properties.

Now every answer and tutorial I've seen about cloning a chunk of HTML like this basically says to do exactly what I'm doing.

I can also see this is a Typescript error, though as I understand it this powers the VS Code JS checks as well, so for the moment I assume it's a valid error (?)

It makes sense that a node wouldn't have an ID like this, but what is the correct way to set the ID and add a class to the outer element of this node when I am doing this? Again, all googling leads me to examples that do exactly what I am doing!


Solution

  • I assume you are cloning an HTMLElement (an HTMLElement derives from Element, which drives from Node).

    Node doesn't have an id attributes, but HTMLElement (and also Element) does.

    All you have to do is tell the compiler the cloned node is something more specific than a Node. E.g.

    const clone = elementToCopy.cloneNode(true) as HTMLElement;
    

    If you really want to be safe, you can explicitly check for it. E.g.:

    const clone = elementToCopy.cloneNode(true)
    if (clone instanceof HTMLElement) {
      clone.id = `js_message_alert_${msg_ct}`
      ...
    }
    

    Up to you.