So here is a philosophical question.
In TypeScript a ChildNode can be parentless, since both ChildNode.parentElement
and ChildNode.parentNode
have a null
type option.
But being ChildNode wouldn't it, by the nature of it, have a parent? I can understand that parentElement
might be null
, since it might derive from a non element node (or would that even be possible) but shouldn't at least parentNode
be non-null?
I understand that it is not really specifically indicated in the DOM spec, but wouldn't it be strange to have a ChildNode
with no parent?
Is it like this in the case that you might move the node away from the parent? But wouldn't something like this change the type of the ChildNode
, to plain ol' Node
?
I would be really interested in having your insight on this question, as it has left me a bit puzzled.
From https://developer.mozilla.org/en-US/docs/Web/API/ChildNode:
The
ChildNode
mixin contains methods and properties that are common to all types ofNode
objects that can have a parent. It's implemented byElement
,DocumentType
, andCharacterData
objects.
ChildNode does not mean "this node currently has a parent node". It's just a mixin that other types implement to include the remove()
, before()
, after()
, and replaceWith()
methods.
An example of a type that inherits from Node but does not mix in the ChildNode methods is Document. A Document is a Node (its children's parentNode
would be itself) but it can never have a parent node, so document.remove()
produces a compilation error.
Is it like this in the case that you might move the node away from the parent? But wouldn't something like this change the type of the
ChildNode
, to plain ol'Node
?
This isn't how TypeScript's static type checking works — calling a method such as remove()
on an object doesn't change its type. (It might be technically possible in JavaScript to change an object's prototype, but TypeScript doesn't model this.) The node is still an object of the same class it was before removal, so it still implements these methods, even though calling them when the node has no parent might not make sense. And in fact, since every Element is a ChildNode, dynamically changing the type after element.remove()
wouldn't make sense because the element should still be an Element.