当我写“
document.querySelector().
”并单击CTRL+空格键触发建议时,style
属性不会得到建议,但它似乎与document.getElementById()
一起工作正常。
为什么会发生这种情况以及如何解决这个问题?
与
querySelector
:与
getElementById
:我希望 IntelliSense 通过“document.querySelector()”建议“style”属性。但事实并非如此。为什么?
如果您很着急并且不关心“为什么”,请跳至本文末尾以获取“解决方案”
这很有趣。根据 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 试图平衡正确性和生产力,我认为让
开始返回需要转换的代码,以获得我们今天在大多数情况下拥有的相同工具支持(例如 JS 上下文中的 HTML 节点)对于 TypeScript 来说这是一个糟糕的选择。getElementById
[...]
另一方面,将其切换为
仍然允许在不常见的情况下以不太激烈的方式设置返回类型: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
的通用参数。