Typescript ChildNode:`parentElement` 和/或`parentNode` 为空?

问题描述

所以这是一个哲学问题。

在 TypeScript 中,子节点可以是无父节点,因为 ChildNode.parentElementChildNode.parentNode 都有 null 类型选项。

但是作为节点,根据它的性质,它不是有一个父节点吗?我可以理解 parentElement 可能是 null,因为它可能来自非元素节点(或者甚至可能),但至少 parentNode 不应该是非空的?

我知道 DOM spec 中并没有特别指明,但是 ChildNode 没有父级会不会很奇怪?

如果您可能将节点从父节点移开,是否是这样?但是这样的事情不会将 ChildNode 的类型更改为普通的 Node 吗?

我真的很想了解您对这个问题的见解,因为它让我有点困惑。

解决方法

来自https://developer.mozilla.org/en-US/docs/Web/API/ChildNode

ChildNode mixin 包含所有类型的 Node 对象通用的方法和属性,这些对象可以有一个父对象。它由 ElementDocumentTypeCharacterData 对象实现。

ChildNode 并不意味着“这个节点当前有一个父节点”。它只是其他类型实现的 mixin,以包含 remove()before()after()replaceWith() 方法。

继承自 Node 但混入 ChildNode 方法的类型的示例是 Document。 Document 是一个节点(它的子节点 parentNode 将是它自己)但它永远不能有父节点,因此 document.remove() 会产生编译错误。

如果您可能将节点从父节点移开,是否是这样?但是这样的事情不会将 ChildNode 的类型更改为普通的 Node 吗?

这不是 TypeScript 的静态类型检查的工作方式——在对象上调用 remove() 之类的方法不会改变其类型。 (技术上可能在 JavaScript 中更改对象的原型,但 TypeScript 不会对此进行建模。)该节点仍然是删除之前的同一类的对象,因此它仍然实现这些方法,即使在调用它们时节点没有父节点可能没有意义。事实上,由于 every Element is a ChildNode,在 element.remove() 之后动态改变类型是没有意义的,因为元素应该仍然是一个元素。