69

在 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): Expected ';'

任何线索为什么?我怀疑我遗漏了一些明显的东西。

4

5 回答 5

85

类型在 TypeScript 中的名称之后,部分原因是类型是可选的

所以你的线:

HTMLElement el = document.getElementById('content');

需要改为:

const el: HTMLElement = document.getElementById('content');

早在 2013 年,类型HTMLElement就会从 的返回值中推断出来,如果您不使用严格的 null 检查(但您应该在 TypeScript 中使用严格模式)getElementById,情况仍然如此。如果您正在执行严格的 null 检查,您会发现返回类型已从 更改为。更改使类型更正确,因为您并不总是找到一个元素。getElementByIdHTMLElementHTMLElement | null

所以当使用类型模式时,编译器会鼓励你使用类型断言来确保你找到了一个元素。像这样:

const el: HTMLElement | null = document.getElementById('content');

if (el) {
  const definitelyAnElement: HTMLElement = el;
}

我已经包含了这些类型来演示运行代码时会发生什么。有趣的是,语句中el的类型更窄,因为您消除了它为空的可能性。HTMLElementif

您可以使用相同的结果类型执行完全相同的操作,而无需任何类型注释。它们将由编译器推断,从而节省所有额外的输入:

const el = document.getElementById('content');

if (el) {
  const definitelyAnElement = el;
}
于 2013-02-07T02:25:51.683 回答
17

好的:奇怪的语法!

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();
};
于 2013-02-07T01:56:24.773 回答
6

在 JavaScript 中,您使用关键字 var、let 或 function 来声明变量或函数。在 TypeScript 类中,您声明的类成员或方法不带这些关键字,后跟冒号和该类成员的类型或接口。

它只是语法糖,没有区别:

var el: HTMLElement = document.getElementById('content');

和:

var el = document.getElementById('content');

另一方面,因为您指定了类型,所以您可以获得 HTMLElement 对象的所有信息。

于 2016-06-08T15:44:04.780 回答
2

尝试像这样为 elementHTML 使用类型:

window.onload = () => {
    var el= <HTMLElement>document.getElementById('content');
    var greeter = new Greeter(el);
    greeter.start();
};

于 2021-09-22T17:43:38.183 回答
1

请注意, const 声明是块范围的。

const el: HTMLElement | null = document.getElementById('content');

if (el) {
  const definitelyAnElement: HTMLElement = el;
}

因此,在 {} 之外无法访问 absoluteAnElement 的值。

(我会在上面发表评论,但显然我没有足够的声誉。)

于 2019-10-01T20:27:03.970 回答