typescript 类型“Element”的参数不能分配给类型“HTMLElement”的参数

mv1qrgav  于 2023-05-01  发布在  TypeScript
关注(0)|答案(2)|浏览(603)
const labelEl: HTMLElement = document.createElement('label')
const isElOfNeededType = (el: HTMLElement): boolean =>
    ["INPUT", "TEXTAREA"].includes(el.tagName);

let result

if (isElOfNeededType(labelEl.nextElementSibling)) {
    result = true
}

这是我的Playground:链接
1.为什么在labelEl.nextElementSibling上出现此错误?
类型“Element”的参数不能分配给类型“HTMLElement”的参数
HTMLElement不是Element的扩展吗?

  • 2.(不是很重要,但如果解释会很高兴)* 为什么TS playground抱怨[ ].includes,而我设置了Config -> Target = esnext
yiytaume

yiytaume1#

labelEl.nextElementSibling的类型为Element。请参见Definitely Typed中的定义。因此,您的代码试图传递Element,其中需要HTMLElement
正如你所说,HTMLElement扩展了Element,但这意味着你可以传递一个Element来代替HTMLElement,因为Element可能没有HTMLElement的属性。但是,您可以在需要Element的地方传递HTMLElement,因为HTMLElement将具有Element的所有属性。
既然你只对Element上的tagName属性感兴趣,我就把你的代码改为使用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
}
vptzau2j

vptzau2j2#

我也有这个问题,尽管背景不同。
正如@Colliere之前的answered一样,问题在于.nextElementSibling返回的是Element,而我们通常需要它作为HTMLElement
一个简单的解决方案是在使用HTMLElement之前将其类型更改为HTMLElement。
在你的例子中,你可以像这样使用类型Assert:

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
}

我使用JSDOC,所以我必须使用JSDOC类型转换(注意额外的括号):

const nextElementSibling = (
        /** @type {HTMLElement} */
        (labelEl.previousElementSibling)
    );

相关问题