【问题标题】:Casting works but declaring type doesn't autocast variables强制转换有效,但声明类型不会自动转换变量
【发布时间】:2021-05-17 16:57:59
【问题描述】:

我是 typescript 的新手,当我为了好玩而制作画布游戏时,我刚开始就遇到了一件奇怪的事情。

// 1) Works but stores HTMLElement, so later fails
const canvas = document.getElementById("game"); 
// 2) Don't works
const canvas: HTMLCanvasElement = document.getElementById("game");
// 3) Works
const canvas = document.getElementById("game") as HTMLCanvasElement; 
// 4) Works
const canvas: HTMLCanvasElement = document.getElementById("game") as HTMLCanvasElement; 

遮阳篷是为什么第二个不起作用,它不应该尝试自动转换为声明的类型吗?我认为最后两个过于冗长或不太清楚。我想知道是否有编译器选项,或者这是否只是发生在我身上。提前致谢。

【问题讨论】:

  • 如果您确定具有给定选择器的元素的类型,您可以添加将选择器映射到相关类型的重载:declare global { interface Document { getElementById(id: "game"): HTMLCanvasElement; } } 在这种情况下,您不需要类型断言。
  • 你也可以这样做:const element = <HTMLCanvasElement>document.getElementById('canvas');

标签: typescript types casting


【解决方案1】:

好吧,document.getElementById 返回 HtmlElement 或 null。它不是能够返回 HtmlCanvasElement 的通用方法。

所以第一行的类型应该是 HtmlElement |空。

作为 HtmlCanvasElement 扩展 HtmlElement 而不是相反。第二行不工作。

第 3 行和第 4 行是相同的,但包含潜在风险,因为如果变量可能为 null => 运行时错误,ide 无济于事。并确定您是否会调用仅在 HtmlCanvasElement 上定义但 id 不是 HtmlCanvasElement 的内容,您会再次看到运行时错误。

最后你应该知道 typescript & types 只是在开发阶段。它可以帮助您开发东西。最后,您的浏览器中的 javascript 知道 javascript 无法理解的类型。

【讨论】:

    【解决方案2】:

    这是因为编译器在运行时不知道你的带有id=game的html标签的类型。

    getElementById 签名看起来像:

    getElementById(elementId: string): HTMLElement | null;
    

    details here

    并且在打字稿中HTMLElement | null 不能分配给HTMLCanvasElement,因为HTMLCanvasElement 只是子类型之一(它可以为空)

    如果您确定,您的标签始终是 HTMLCanvasElement 类型,您可以告诉编译器

    嘿伙计!我知道这个函数在运行时总是返回HTMLCanvasElement。相信我!

    您可以使用带有 as 关键字的工作示例之一

    【讨论】:

      猜你喜欢
      • 2014-02-16
      • 2017-10-28
      • 2021-01-24
      • 1970-01-01
      • 2012-06-20
      • 1970-01-01
      • 2018-09-11
      • 1970-01-01
      • 2015-08-17
      相关资源
      最近更新 更多