Reputation: 3592
const labelEl: HTMLElement = document.createElement('label')
const isElOfNeededType = (el: HTMLElement): boolean =>
["INPUT", "TEXTAREA"].includes(el.tagName);
let result
if (isElOfNeededType(labelEl.nextElementSibling)) {
result = true
}
Here's my playground: link
labelEl.nextElementSibling
?
Argument of type 'Element' is not assignable to parameter of type 'HTMLElement'
Doesn't HTMLElement
extend Element
?
2. (not really important, but would be glad if explained) Why does TS playground complains about [ ].includes
whereas I've set Config -> Target = esnext
?
Upvotes: 3
Views: 7464
Reputation: 2607
I also had this issue, even though the context was different.
As previously answered by @Colliere, the
problem is that .nextElementSibling
is returning an Element
, while we often need it as an HTMLElement
.
A straightforward solution is change the type to HTMLElement before using it.
In your example you can use type assertion like this:
const labelEl: HTMLElement = document.createElement('label')
const isElOfNeededType = (el: HTMLElement): boolean =>
["INPUT", "TEXTAREA"].includes(el.tagName);
let result
if (isElOfNeededType(labelEl.nextElementSibling as HTMLElement)) {
result = true
}
I used JSDOC, so I had to use JSDOC type casting (note the extra parentheses):
const nextElementSibling = (
/** @type {HTMLElement} */
(labelEl.previousElementSibling)
);
Upvotes: 1
Reputation: 956
labelEl.nextElementSibling
is of type Element
. See the definition in Definitely Typed. So your code is trying to pass an Element
where an HTMLElement
is required.
As you say, HTMLElement
extends Element
, but this does mean you can pass an Element
in place of an HTMLElement
, because the Element
may not have properties that an HTMLElement
does. You could however pass an HTMLElement
where an Element
is expected, because an HTMLElement
will have all the properties of an Element
.
Seeing as you are only interested in the tagName
property, which exists on Element
I would just change your code to use Element
.
const labelEl: HTMLElement = document.createElement('label')
const isElOfNeededType = (el: Element): boolean =>
["INPUT", "TEXTAREA"].includes(el.tagName);
let result
if (isElOfNeededType(labelEl.nextElementSibling)) {
result = true
}
Upvotes: 2