本文详解在TypeScript中使用getElementById等DOM方法时遇到的类型错误。由于返回值为通用的HTMLElement,无法直接访问特定元素属性。通过类型断言或转换为具体子类接口(如HTMLInputElement),可安全获取DOM节点内容并避免编译报错。
简述
简述
Angular 1.x版本是基于JavaScript开发的,网络上常搜索到的AngularJS即指代该版本,并非JavaScript的衍生分支。后续版本改用TypeScript重写框架,因改动巨大而进行了命名区分:v1.x称为AngularJS,v2及以上版本统称为Angular。
查阅资料或解决方案时,常会搜索到大量AngularJS相关内容,需注意区分版本差异。
提及Angular历史背景,是因为本文内容基于该框架的实际使用场景,故简要说明。
问题背景
问题背景
假设存在如下HTML文件结构:
<!-- 这俩随便挑一个用就行 -->
<input type="text" id="infoInput" name="infoInput">
<textarea id="infoArea" name="infoArea" rows="8" cols="80"></textarea>
<!-- 这俩也随便挑一个用就行 -->
<span id="some">something happen!</span>
<p id="any">anything ok!</p>
若需通过TypeScript获取上述任意一个DOM元素,具备JavaScript基础者可知,操作DOM通常借助document对象完成:
// 由于DOM元素的ID是惟一的,所以这种方式获取的是唯一的DOM元素
dom = document.getElementById('infoInput');
// name属性是不唯一的,所以这种方式获取的是所有 name=infoInput 的DOM元素,即一个数组
dom1 = document.getElementsByName('infoInput');
在TypeScript中同样可行,但具体使用时,除声明变量保存获取到的DOM元素外,还存在一个细微问题。
// Angular框架中
export class Some implements OnInit {
ngOnInit() {
let dom = document.getElementById('infoArea');
// 1. 获取输入框中的内容
let html = dom.innerHTML;
let val = dom.value;
// 2. 打印输出
console.log(html);
console.log(val);
}
}
编写该代码后会出现编译错误:
Property 'value' does not exist on type 'HTMLElement'。此错误无需过度担忧,即使存在提示,代码仍可运行并返回正确结果。若希望编译失败时不生成JS文件,可通过配置实现。
HTMLElement是什么?这是一个包含所有HTML元素共有属性的对象。
关于HTMLElement的详细内容及浏览器兼容性,可参考MDN的相关文章。
参考下图:

图片来源为nanaistaken的博客。
若具备面向对象编程知识,理解此图较为容易;若无相关背景也无妨,因为无论是JS还是TS,现已引入class关键字及类思想。
经分析可知:getElementXXX()返回的是HTMLElement对象,该对象包含所有DOM元素的公有属性。而各类特定DOM元素拥有自身特性,即图中的子类。
TypeScript会进行编译检查,因此产生错误提示;JavaScript不检查,这可能留下安全隐患。
至此,应已明确当前情况的解决方法及后续使用getElementXXX函数的规范。
修改后的代码示例如下:
export class Some implements OnInit {
ngOnInit() {
// *. 做一次类型转换,或者做类型断言
let dom = <HTMLInputElement>document.getElementById('infoArea');
let dom1 = document.getElementById('infoArea') as HTMLElement;
// 1. 获取输入框中的内容
let html = dom.innerHTML;
let val = dom.value;
// 2. 打印输出
console.log(html);
console.log(val);
}
}
总结
总结
HTMLElement是DOM节点共有的属性集合,TypeScript库将其抽取为公共接口,类似于Java和C++中的基类概念。此举旨在确保操作DOM节点时不会访问不存在的属性。
HTMLInputElement是HTMLElement的一个子接口(或称子类,鉴于TypeScript支持class,称接口更为准确),其内部封装了input、textarea等DOM节点的属性。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。