TypeScript 2.8.1中Node.attributes属性移除原因及替代方案咨询
嘿,这个问题我之前升级TS版本的时候也踩过坑,给你详细说说哈:
为什么Node.attributes被移除了?
其实是TypeScript 2.8.1对DOM类型的定义做了更贴近W3C标准的修正。之前旧版TS里把attributes属性放到了所有Node类型上,但按照标准DOM规范,attributes是Element类型专属的——像文本节点(Text)、注释节点(Comment)这些Node的子类根本就没有attributes属性。所以TS团队在这个版本做了破坏性变更,把attributes从Node的类型定义里拿掉了,只保留在Element及其子类上,这样类型检查更严格,也更符合实际的DOM行为。
可行的替代方案
类型断言+类型检查(最推荐)
如果你的代码里这个node本来就是Element(比如从document.getElementById、querySelector拿到的),直接用类型断言就能解决,还能保留TS的类型校验:
const attribs = (node as Element).attributes;
要是不确定node是不是Element,最好先做个类型判断,避免运行时出错:
if (node instanceof Element) { const attribs = node.attributes; // 这里放心处理属性就行 } else { // 处理非Element节点的情况,比如给个提示或者跳过 }
你目前用的索引访问方式
node['attributes']确实能绕开TS的类型检查,让代码编译通过,但缺点很明显——你失去了TS最核心的类型校验优势。如果哪天某个地方的node真的是个没有attributes的Text节点,运行时就会出问题,而且TS不会提前给你报错。所以这种方式只能临时救急,不建议长期用。
扩展Node类型(谨慎使用)
要是你的代码里有大量地方都在Node上用attributes,不想一个个改,可以通过类型扩展强制给Node加上这个属性,但这是不符合标准的,一定要谨慎:
declare global { interface Node { attributes: NamedNodeMap; } }
用这个方法的前提是你能100%保证所有用到的Node都是Element,否则会埋下运行时隐患。
内容的提问来源于stack exchange,提问作者AlvinfromDiaspar

