为什么 document.getElementById() 的结果是 TypeScript 建议的样式属性,而不是 document.querySelector() 的结果?

问题描述 投票:0回答:1

当我写“

document.querySelector().
”并单击CTRL+空格键触发建议时,
style
属性不会得到建议,但它似乎与
document.getElementById()
一起工作正常。

为什么会发生这种情况以及如何解决这个问题?

querySelector

getElementById

我希望 IntelliSense 通过“document.querySelector()”建议“style”属性。但事实并非如此。为什么?

typescript visual-studio-code intellisense
1个回答
2
投票

如果您很着急并且不关心“为什么”,请跳至本文末尾以获取“解决方案”

这很有趣。根据 DOM 标准,

querySelector
getElementById
都返回
Element
实例,或
null

文档:

但是,在 lib.dom.ts 中,键入

querySelector
将返回
Element | null
,对于 HTML 文档,键入
getElementById
将返回
HTMLElement | null
。并且
style
DOM 属性是在
HTMLElement
上定义的,但不是在
Element
上定义的。

这已经在 TypeScript GitHub 存储库的问题跟踪器中提出:

Document.getElementById()
必须返回
Element
,而不是
HTMLElement
#19549
,已关闭以将该问题的讨论移至 Node.parentElement 应该是 Element,而不是 HTMLElement #4689。您可以关注那里的讨论。以下是维护者对此事的一些看法:

这是有争议的,因为之前有人抱怨说总是将类型

Element
转换为
HTMLElement
太麻烦了,而在大多数常见情况下,实际类型是
HTMLElement
,即使规范说它应该是
 Element

例如,

getElementById
的返回类型定义为
Element
,但是我们将其设为
HTMLElement
以避免过多的转换。如果类型是其他
Element
,您可以先将其转换为
Element
,然后再次将其转换为最终类型。我认为在大多数情况下
parentElement
也是
HTMLElement
,因此最好保持原样。

- 正卜力

@jun-sheaf 为这些更改发送了 PR,我一直在审查是否应该将其纳入 4.1。

我认为我们不应该进行这些更改,因为这会以人们不会认为对他们有利的方式添加中断大量代码。 TS 试图平衡正确性和生产力,我认为让

getElementById
开始返回需要转换的代码,以获得我们今天在大多数情况下拥有的相同工具支持(例如 JS 上下文中的 HTML 节点)对于 TypeScript 来说这是一个糟糕的选择。

[...]

另一方面,将其切换为

getElementById<E extends Element = HTMLElement>(elementId: string): E | null
仍然允许在不常见的情况下以不太激烈的方式设置返回类型:

const logo2 = getElementById2("my-logo") as SVGPathElement
const logo3 = getElementById2<SVGPathElement>("my-logo")

但不妨碍默认的 JS 工具支持。

- 奥尔塔

该问题已通过此提交完成:

d561e08
,这基本上完成了 orta 所谈论的
getElementById
。 IE。如果我理解正确的话,它仍然会为 HTML 文档返回
HTMLElement
(但不会返回 SVG 或 XML 等其他类型的文档)。

换句话说,一切都按照 TypeScript 维护者编写的功能运行。

如果您希望

style
属性在
querySelector
的结果上可用,则使用类型断言(使用
HTMLElement
)或使用 JSDoc 注释将其类型转换为
as HTMLElement
,或者执行运行时使用
if (foo instanceof HTML...Element) {...}
进行类型检查,或使用
querySelector
的通用参数。

© www.soinside.com 2019 - 2024. All rights reserved.