首页 > 解决方案 > 为什么 querySelectorAll('div') 返回 HTMLDivElement 列表但 querySelectorAll('div.className') 返回 TypeScript 中的 Element 列表

问题描述

我想知道为什么当您将类名放入 querySelectorAll 时,该类型不再显示为 HTMLDivElement。

document.querySelectorAll('div').forEach(item => {
    // item type is HTMLDivElement
});

document.querySelectorAll('div.className').forEach(item => {
    // item type is Element not HTMLDivElement
});

这意味着如果我想更改样式,则会出现错误:

document.querySelectorAll('div').forEach(item => {
    item.style.display = 'none';
});

document.querySelectorAll('div.className').forEach(item => {
    item.style.display = 'none'; // TS2339: Property 'style' does not exist on type 'Element'.
});

我已经找到了一些解决方法(如下),但我很好奇为什么它甚至是必要的。

// Cast all items in NodeList to HTMLDivElement type
document.querySelectorAll<HTMLDivElement>('div.className').forEach(item => {
    item.style.display = 'none';
});

// Cast current item to HTMLDivElement type
document.querySelectorAll('div.className').forEach(item => {
    (item as HTMLDivElement).style.display = 'none';
});

// Only change style.display if instanceof HTMLDivElement
document.querySelectorAll('div.className').forEach(item => {
    if (item instanceof HTMLDivElement) item.style.display = 'none';
});

标签: typescript

解决方案


定义在这里:

https://github.com/microsoft/TypeScript/blob/master/lib/lib.dom.d.ts#L11347

(永久链接到当前版本,以防它稍后移动:https ://github.com/microsoft/TypeScript/blob/4a7b6dc7497db7847bfa01c2e747fb5e7c200224/lib/lib.dom.d.ts#L11347 )

看起来,它们对已知的 HTML 和 SVG 元素有专门的定义,在这些情况下返回更具体的列表。我会说你的

document.querySelectorAll<HTMLDivElement>('div.className')

是其他情况的正确解决方案。


推荐阅读