【问题标题】:JavaScript type annotationsJavaScript 类型注解
【发布时间】:2015-02-11 17:31:31
【问题描述】:

我在使用 WebStorm 遇到以下问题:

/** @type {HTMLCanvasElement} */
var buffered_canvas = document.createElement("canvas");
buffered_canvas.width = 256;
buffered_canvas.height = 256;

当我将 buffered_canvas 注释为 HTMLCanvasElement 类型时,它抱怨 createElement 返回的 HTMLElement 无法分配给 HTMLCanvasElement。

/** @type {HTMLElement} */
var buffered_canvas = document.createElement("canvas");
buffered_canvas.width = 256;
buffered_canvas.height = 256;

当我将其更改为 HTMLElement 类型时,它会抱怨 HTMLElement 上未定义宽度和高度属性。

我该如何正确地做到这一点?

另外——我是 JavaScript 新手,很难找到任何真正的规范,例如 HTMLElement 及其具有的属性或 createCanvas 的方法签名以及它返回的类型。有时我会在 MDN 上找到不错的东西,但它们通常不包含方法签名或太多类型信息。这东西有什么好的资源吗?

谢谢

【问题讨论】:

  • 我会说你不必要地让你的工作变得复杂。 JavaScript 不是强类型的,Java 也不是。
  • 嗯,我的项目目前是 20K 行代码,所以很复杂。我正在使用 Closure Compiler 并键入注释来检查错误。我承认我是 WebStorm 的新手,但它内置的错误检查已经帮助我发现了一些错误。但是,它也列出了数百个类似上述的愚蠢错误。

标签: javascript types webstorm


【解决方案1】:

您可以像这样键入 cast:

var buffered_canvas = /** @type {HTMLCanvasElement} */ (document.createElement("canvas"));

请参阅bottom of this page

您可以将其与常规类型注释一起使用,如下所示。

/** @type {HTMLCanvasElement} */
var buffered_canvas = /** @type {HTMLCanvasElement} */ (document.createElement("canvas"));

如果 WebStorm 遵循与 Closure 相同的注释约定,这应该可以工作。

很难找到任何真正的规范,例如 HTMLElement 及其具有的属性或 createCanvas 的方法签名以及返回的类型。

MDN不错,标准也可以看WHATWGW3C

【讨论】:

  • 谢谢,这似乎是最好的解决方案。并感谢您的链接。 :-)
【解决方案2】:

两全其美,将类型设置为任一或使用管道运算符|

/** @type {HTMLCanvasElement|HTMLElement} */

现在您的 IDE 将识别这两种继承的方法。

这样做没关系,因为HTMLCanvasElement 实际上扩展了HTMLElement。 当你这样做时,你是在告诉 IDE 2 件事:

  1. 首先你有一个HTMLCanvasElement,因为我们知道createElement('canvas')返回的HTMLElement是从new HTMLCanvasElement()转换为HTMLElement。这样就满足了您的第二个问题:

当我将其更改为 HTMLElement 类型时,它会抱怨 HTMLElement 上未定义宽度和高度属性。

  1. 第二个你有一个HTMLElement,因为继承HTMLCanvasElement.prototype = new HTMLElement(),所以这将满足你的第一个问题:

当我将 buffered_canvas 注释为 HTMLCanvasElement 类型时,它抱怨 createElement 返回的 HTMLElement 无法分配给 HTMLCanvasElement。

编辑

进一步检查准确性,这是 PHPStorm(我假设 WebStorm 也是如此)用于document.createElement的内容@

/**
@param {string} tagName
@return {Element}
*/
Document.prototype.createElement = function(tagName) {};

这是矛盾的,当您将鼠标悬停在方法 createElement 上时,您会在弹出窗口中看到

[ HTMLElement ] Document.prototype.createElement( [ string ] tagName )

最后,和之前一样的原理HTMLElement扩展Element,所以你可以使用这个注解

/** @type {Element|HTMLElement|HTMLCanvasElement} */
var buffered_canvas = document.createElement("canvas");

【讨论】:

  • 这基本上与不输入类型相同(查看 Closure 的输入百分比输出)。有点失败了。
  • 你错了。看我的编辑。 HTMLCanvasElementHTMLElement
  • 啊,所以 WebStorm 将为您提供两种类型的自动完成功能。这实际上会在 Closure 中引发警告,因为它需要来自 createElement 而不是 HTMLElement 的元素。如果您执行 HTMLCanvasElement|Element,它不会发出警告,但它几乎没用,因为它会将其视为无类型。类型转换是否不适用于 WebStorm?
  • @DaggNabbit 是的,它会的。对于元素的事情,请参阅我的编辑 webstorm/phpstorm 自相矛盾
  • @DaggNabbit 我不确定转换是否在 webstorm/phpstorm 中有效,我使用 | 来继承类型提示的方法
猜你喜欢
  • 2019-07-27
  • 2012-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-06
  • 1970-01-01
相关资源
最近更新 更多