属性 'id' 在 cloneNode 后的普通 JS 中不存在于类型 'Node' 上

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

我有一个纯 JS 函数,可以根据一大块“模板”向页面添加消息 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 代码抱怨 clone.idclone.classList 因为节点不能具有这些属性。

现在我看到的每一个关于克隆一大块 HTML 的答案和教程基本上都说要完全按照我正在做的去做。

我还可以看出这是一个 Typescript 错误,尽管据我了解,这也支持 VS Code JS 检查,所以目前我认为这是一个有效错误 (?)

节点没有这样的 ID 是有道理的,但是当我这样做时设置 ID 并向该节点的外部元素添加 class 的正确方法是什么?同样,所有谷歌搜索都让我找到了与我正在做的完全一样的例子!

您可以通过使用 JSDOC 指定它的类型来修复它,例如:

/** @type {HTMLElement} */
const clone = elementToCopy.cloneNode(true);

更好的方法是 instanceof:

const clone = elementToCpoy.cloneNode(true);
if (clone instanceof HTMLElement) {
    ...
}

我假设您正在克隆一个 HTMLElement(一个 HTMLElement 派生自 Element,它从 Node 驱动)。

节点没有 id 属性,但是 HTMLElement(以及 Element)有。

您所要做的就是告诉编译器克隆的节点比 Node 更具体。例如

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

如果你真的想要安全,你可以明确地检查它。例如:

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

由你决定。