关闭包含构造函数

时间:2016-09-21 07:35:05

标签: javascript types module google-closure-compiler

我正在试图检查一个返回构造函数Object的库。使用以下代码Closure错误:

./my-app.js:11: ERROR - Cannot call non-function type Foo.Wheel
const wheel = new Foo.Wheel();
               ^

这是代码结构:

my-app-code.js - 我正在使用的代码

const Foo = /** @type{!Foo.Module} */ require('foo');
const wheel = new Foo.Wheel();
wheel.rotate();

externs-foo.js - Foo库的关闭外部

/** @const */
const Foo = {};


/** @record */
Foo.Module = function() {};

/** @type {!Foo.Wheel} */
Foo.Module.prototype.Wheel;

/** @constructor */
Foo.Wheel = function() {};

/**
* @returns {void}
*/
Foo.Wheel.prototype.rotate = function() {};

foo / index.js - 对应于Foo.Module类型。

module.exports = {
  Wheel: require("./wheel"),
};

foo / wheel.js - 对应于Foo.Wheel。

function Wheel() {}

Wheel.prototype.rotate = function() {};

module.exports = Wheel;

我在externs-foo.js上尝试了一个变体,结果如下。

Foo.module.prototype.Wheel成为一个功能

/** @return {!Foo.Wheel} */
Foo.Module.prototype.Wheel = function() {};

错误:

my-app.js:11: ERROR - Expected a constructor but found type function(this:Foo.Module):Foo.Wheel.
const wheel = new Foo.Wheel();

my-app.js:13: ERROR - Property rotate never defined on module$myapp_Foo of type Foo.Module
wheel.rotate();

1 个答案:

答案 0 :(得分:2)

我知道这个问题的两个解决方案:

  1. 在外部文件中声明Foo.Module.prototype.Wheel = Foo.Wheel;
  2. 使用@type {function(new:Foo.Wheel)},表示该函数实际上是一个实例化Foo.Wheel对象的构造函数。
  3. 我更喜欢解决方案#1,因为它声明了对构造函数的引用,因此编译器将允许我访问构造函数的属性(例如静态方法)。 IIRC不能在解决方案#2中完成。

    注释@type {!Foo.Wheel}@return {!Foo.Wheel}无法正常工作,因为它们引用了Foo.Wheel的实例,而您实际需要的是构造函数本身。