如何在代码包装在函数中时定义全局类型

时间:2014-05-16 19:55:45

标签: javascript google-closure-compiler google-closure

这个问题是关于正确使用Google Closure Compiler的类型注释。

我们有一个约定,即每个javascript文件都包含在一个函数中。示例文件:

Square.js

(function() {
    'use strict';

    /**
     * @constructor
     */
    function Square() {};

    Square.prototype.draw = function() {
    };

}());

如果我们在这个函数中定义一个类型(比如构造函数),那么闭包编译器在其他文件中并不知道它。例如,在另一个文件中:

foo.js

(function() {
    'use strict';

    /** @param {Square} square */
    function drawSquare(square) {
        square.draw();
    }

}());

使用-W VERBOSE进行编译会出现错误,指出类型Square未定义:

foo.js:4: WARNING - Bad type annotation. Unknown type Square
        /** @type {Square} square */
                   ^

0 error(s), 1 warning(s), 83.3% typed

我们已经在单独的文件中为所有类创建了externs来解决这个问题。创建externs是一个糟糕的解决方案,因为现在我们必须为每个类维护两个文件。

  1. 如果文件由文件级函数包装,是否可以共享类型?
  2. 在文件之间共享类型时,一般使用闭包的推荐方法是什么?使用闭包库是否以任何方式提供/需要帮助?

1 个答案:

答案 0 :(得分:2)

我想你可以通过在封闭函数的限制范围之外导出带有你想要使用的名称的符号来设法使它工作。像这样:

(function() {
    goog.provide('Square');
    //'use strict';

    /**
     * @constructor
     */
    function Square() {};

    Square.prototype.draw = function() {
      return "\\o/";
    };
    goog.exportSymbol('Square', Square);
}());

但是,我认为你的问题在这里:

  

我们有一个约定,即每个javascript文件都包含在一个函数中。

Closure有一个不同的约定,即define namespaces

要回答第二个问题,推荐的关闭方式是:

goog.provide('my.Square');
/**
 * @constructor
 */
my.Square = function() {
};

my.Square.prototype.draw = function() {
  // TODO
};

goog.provide('my.App');

goog.require('my.Square');


/**
 * @param {my.Square} square The square to draw
 */
my.App.prototype.drawSquare = function(square) {
  square.draw();
};