首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >TypeScript:类型系统的问题

TypeScript:类型系统的问题
EN

Stack Overflow用户
提问于 2012-12-02 12:46:37
回答 8查看 90.6K关注 0票数 116

我只是在测试VisualStudio 2012的类型记录,它的类型系统有问题。我的html站点有一个带有id "mycanvas“的画布标记。我想在这张帆布上画一个长方形。这是密码

代码语言:javascript
运行
复制
var canvas = document.getElementById("mycanvas");
var ctx: CanvasRenderingContext2D = canvas.getContext("2d");
ctx.fillStyle = "#00FF00";
ctx.fillRect(0, 0, 100, 100);

不幸的是,VisualStudio抱怨

属性“getContext”在“HTMLElement”类型的值上不存在

它将第二行标记为错误。我以为这只是一个警告,但代码没有编译。VisualStudio说

存在构建错误。是否继续并运行上一次成功的构建?

我一点也不喜欢这个错误。为什么没有动态方法调用?毕竟,getContext方法肯定存在于我的画布元素中。然而,我认为这个问题很容易解决。我刚刚为画布添加了一个类型分析:

代码语言:javascript
运行
复制
var canvas : HTMLCanvasElement = document.getElementById("mycanvas");
var ctx: CanvasRenderingContext2D = canvas.getContext("2d");
ctx.fillStyle = "#00FF00";
ctx.fillRect(0, 0, 100, 100);

但类型体系仍不满意。下面是新的错误消息,这次是在第一行:

无法将“HTMLElement”转换为“HTMLCanvasElement”:键入“HTMLElement”缺少“HTMLCanvasElement”中的“toDataURL”属性

好吧,我完全支持静态输入,但这使得语言无法使用。类型系统要我做什么?

更新:

类型记录实际上不支持动态调用,我的问题可以通过类型转换来解决。我的问题基本上是这个TypeScript:铸造HTMLElement的重复

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2012-12-02 16:23:13

代码语言:javascript
运行
复制
var canvas = <HTMLCanvasElement> document.getElementById("mycanvas");
var ctx = canvas.getContext("2d");

或者使用any类型的动态查找(没有打字):

代码语言:javascript
运行
复制
var canvas : any = document.getElementById("mycanvas");
var ctx = canvas.getContext("2d");

您可以查看lib.d.ts中的不同类型。

票数 254
EN

Stack Overflow用户

发布于 2019-02-12 23:55:07

代码语言:javascript
运行
复制
const canvas =  document.getElementById('stage') as HTMLCanvasElement;
票数 19
EN

Stack Overflow用户

发布于 2019-02-13 03:23:57

虽然其他答案促进类型断言(这就是事实-- TypeScript没有真正改变类型的类型转换;它们只是一种抑制类型检查错误的方法),但明智地诚实地解决问题的方法是倾听错误消息。

在你的例子中,有三件事情可能出错:

  • document.getElementById("mycanvas")可能返回null,因为没有找到该id的节点(它可能已被重命名,尚未注入到文档中,可能有人尝试在没有访问DOM的环境中运行您的函数)。
  • document.getElementById("mycanvas")可能返回对DOM元素的引用,但此DOM元素不是HTMLCanvasElement
  • document.getElementById("mycanvas")确实返回了一个有效的HTMLElement,它确实是一个HTMLCanvasElement,但是浏览器不支持CanvasRenderingContext2D

我建议您控制应用程序边界,而不是告诉编译器闭嘴(可能会发现自己处于抛出无用错误消息(如Cannot read property 'getContext' of null )的情况下)。

确保元素包含一个HTMLCanvasElement

代码语言:javascript
运行
复制
const getCanvasElementById = (id: string): HTMLCanvasElement => {
    const canvas = document.getElementById(id);

    if (!(canvas instanceof HTMLCanvasElement)) {
        throw new Error(`The element of id "${id}" is not a HTMLCanvasElement. Make sure a <canvas id="${id}""> element is present in the document.`);
    }

    return canvas;
}

确保浏览器支持呈现上下文

代码语言:javascript
运行
复制
const getCanvasRenderingContext2D = (canvas: HTMLCanvasElement): CanvasRenderingContext2D => {
    const context = canvas.getContext('2d');

    if (context === null) {
        throw new Error('This browser does not support 2-dimensional canvas rendering contexts.');
    }

    return context;
}

用法:

代码语言:javascript
运行
复制
const ctx: CanvasRenderingContext2D = getCanvasRenderingContext2D(getCanvasElementById('mycanvas'))

ctx.fillStyle = "#00FF00";
ctx.fillRect(0, 0, 100, 100);

TypeScript游乐场

票数 14
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13669404

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档