我只是在2012年的VisualStudio测试打字稿,并与它的类型系统出了问题。 我的HTML网站有id为“mycanvas”在画布标记。 我想得出这样的画布上的矩形。 下面的代码
var canvas = document.getElementById("mycanvas");
var ctx: CanvasRenderingContext2D = canvas.getContext("2d");
ctx.fillStyle = "#00FF00";
ctx.fillRect(0, 0, 100, 100);
不幸的是VisualStudio的抱怨
财产“的getContext”确实对类型“HTML元素”的值不存在
它标志着第二行为错误。 我认为这将是仅仅是一个警告,但代码不编译。 VisualStudio中说,
有生成错误。 你想继续和运行上次成功构建?
我不喜欢这样的错误的。 为什么没有动态方法调用? 所有的方法后的getContext肯定存在我的画布元素。 不过,我认为这个问题很容易解决。 我只是增加了画布类型annotiation:
var canvas : HTMLCanvasElement = document.getElementById("mycanvas");
var ctx: CanvasRenderingContext2D = canvas.getContext("2d");
ctx.fillStyle = "#00FF00";
ctx.fillRect(0, 0, 100, 100);
但类型系统还不满意。 这里是新的错误消息,这一次在第一行:
无法将“HTML元素”到“HTMLCanvasElement”:从类型类型“HTML元素”缺少财产“toDataURL“HTMLCanvasElement”
好吧,我全力以赴为静态类型,但是这使语言无法使用。 是什么类型的系统要我怎么做?
更新:
打字稿也的确动态调用不支持,我的问题可以用类型转换来解决。 我的问题基本上是这样一个的副本打字稿:铸造HTML元素
var canvas = <HTMLCanvasElement> document.getElementById("mycanvas");
var ctx = canvas.getContext("2d");
或使用动态查找与any
类型(无类型检查):
var canvas : any = document.getElementById("mycanvas");
var ctx = canvas.getContext("2d");
你可以看一下不同类型的lib.d.ts 。
看来这是打字稿的0.9版本被纠正: http://blogs.msdn.com/b/typescript/archive/2013/03/25/working-on-typescript-0-9-generics-overload-关于常数和编译器,performance.aspx参见在canvas标签明确表示“对常量超载”一节。
我有同样的问题,但随着SVGSVGElement而不是HTMLCanvasElement。 铸造到SVGSVGElement给了一个编译时错误:
var mySvg = <SVGSVGElement>document.getElementById('mySvg');
无法将“HTML元素”到“SVGSVGElement”:
类型“HTMLElement的”缺少从类型“SVGSVGElement”属性的“width”。
类型“SVGSVGElement”缺少财产型“OnMouseLeave在“HTML元素”。
如果第一铸造“任意”固定它:
var mySvg = <SVGSVGElement><any>document.getElementById('mySvg');
或这种方式(它具有相同的效果)
var mySvg: SVGSVGElement = <any>document.getElementById('mySvg');
现在mySvg是强类型为SVGSVGElement。
const canvas = document.getElementById('stage') as HTMLCanvasElement;
而其他的答案推动型的断言(这是它们是什么-打字稿没有类型转换 ,实际上改变的类型;它们仅仅是抑制类型检查错误的方式),在理智的诚实方式来处理你的问题是听错误消息。
在你的情况下,有3件事情可能出错:
-
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
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;
}
确保渲染上下文浏览器支持
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;
}
用法:
const ctx: CanvasRenderingContext2D = getCanvasRenderingContext2D(getCanvasElementById('mycanvas'))
ctx.fillStyle = "#00FF00";
ctx.fillRect(0, 0, 100, 100);
见打字稿游乐场 。