在visual studio的默认TypeScript HTML应用程序中,我添加了
HTMLElement
到window.onload事件处理程序的第一行,认为我可以为“el”提供一个类型。
因此:
class Greeter {
element: HTMLElement;
span: HTMLElement;
timerToken: number;
constructor (element: HTMLElement) {
this.element = element;
this.element.innerText += "The time is: ";
this.span = document.createElement('span');
this.element.appendChild(this.span);
this.span.innerText = new Date().toUTCString();
}
start() {
this.timerToken = setInterval(() => this.span.innerText = new Date().toUTCString(), 500);
}
stop() {
clearTimeout(this.timerToken);
}
}
window.onload = () => {
HTMLElement el = document.getElementById('content');
var greeter = new Greeter(el);
greeter.start();
};
我收到错误
编译错误。有关详细信息,请参阅错误列表... / app.ts(25,17): 预期';'
有什么线索的原因?我怀疑我错过了一些明显的东西。
答案 0 :(得分:33)
类型来自之后在TypeScript中的名称,部分原因是类型是可选的。
所以你的行:
HTMLElement el = document.getElementById('content');
需要改为:
const el: HTMLElement = document.getElementById('content');
早在2013年,类型HTMLElement
将从getElementById
的返回值推断出来,如果您没有使用严格的空检查,仍然是 (但你应该使用TypeScript中的严格模式)。如果您正在执行严格的空检查,您会发现getElementById
的返回类型已从HTMLElement
更改为HTMLElement | null
。更改使类型更正确,因为您并不总是找到元素。
因此,在使用类型模式时,编译器会鼓励您使用类型断言来确保找到元素。像这样:
const el: HTMLElement | null = document.getElementById('content');
if (el) {
const definitelyAnElement: HTMLElement = el;
}
我已经包含了类型来演示运行代码时会发生什么。有趣的是,el
在HTMLElement
语句中具有较窄的类型if
,因为您消除了它为空的可能性。
您可以使用相同的结果类型执行完全相同的操作,而无需任何类型注释。它们将由编译器推断,从而节省了所有额外的输入:
const el = document.getElementById('content');
if (el) {
const definitelyAnElement = el;
}
答案 1 :(得分:14)
好的:奇怪的语法!
var el: HTMLElement = document.getElementById('content');
解决了这个问题。我想知道为什么这个例子首先没有这样做?
完整代码:
class Greeter {
element: HTMLElement;
span: HTMLElement;
timerToken: number;
constructor (element: HTMLElement) {
this.element = element;
this.element.innerText += "The time is: ";
this.span = document.createElement('span');
this.element.appendChild(this.span);
this.span.innerText = new Date().toUTCString();
}
start() {
this.timerToken = setInterval(() => this.span.innerText = new Date().toUTCString(), 500);
}
stop() {
clearTimeout(this.timerToken);
}
}
window.onload = () => {
var el: HTMLElement = document.getElementById('content');
var greeter = new Greeter(el);
greeter.start();
};
答案 2 :(得分:5)
在JavaScript中,您可以使用关键字var,let或function声明变量或函数。在TypeScript类中,您声明没有这些关键字的类成员或方法,后跟冒号以及该类成员的类型或接口。
这只是语法糖,没有区别:
var el: HTMLElement = document.getElementById('content');
和
var el = document.getElementById('content');
另一方面,因为您指定了类型,所以您获得了HTMLElement对象的所有信息。
答案 3 :(得分:0)
请注意,const声明是基于块范围的。
const el: HTMLElement | null = document.getElementById('content');
if (el) {
const definitelyAnElement: HTMLElement = el;
}
因此,在{}之外无法访问absoluteAnElement的值。
(我上面已经评论过,但是我的声誉显然不足。)