错误类型注释。未知类型

时间:2013-06-14 08:10:32

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

我一直收到上面提到的警告,但无法弄清楚原因。我添加了deps.js,deps.js包含对类型的引用。

以下是有问题的代码:

goog.provide("MyCompany.MyApp.dom");


MyCompany.MyApp.dom.getArticleAmountInput_=function(){
    return document.getElementById("articleAmount");
};
/**
 * Gets the article amount input value
 * @type {function(this:MyCompany.MyApp.dom):number} */
MyCompany.MyApp.dom.getArticleAmount=function(){
    var tmp=this.getArticleAmountInput_();
    return (tmp)?tmp.value():undefined;
};

在deps.js中:

goog.addDependency('../../MyCompany/MyApp/dom.js', [ 'MyCompany.MyApp.dom'], []);

代码在html中加载,因此它确实在运行时找到了类。以下是我编译代码的方法:

java -jar ../../compiler.jar \
--compilation_level=ADVANCED_OPTIMIZATIONS \
--formatting=PRETTY_PRINT \
--warning_level=VERBOSE \
--summary_detail_level=3 \
--js=MyCompany/MyApp/dom.js \
--js=closure/goog/deps.js \
--js_output_file=out.js

它一直在给我警告:

  

警告 - 错误类型注释。未知类型MyCompany.MyApp.dom

[更新]

尝试完全忽略goog.provide并在编译时忽略js=closure/goog/deps.js并将所有内容更改为小写,但在此代码上仍然收到相同的警告:

//goog.provide("mycompany.myapp.dom");
var mycompany={};
mycompany.myapp={};
mycompany.myapp.dom={};

mycompany.myapp.dom.getArticleAmountInput_=function(){
    return document.getElementById("articleAmount");
};
/**
 * Gets the article amount input value
 * @type {function(this:mycompany.myapp.dom):number} */
mycompany.myapp.dom.getArticleAmount=function(){
    var tmp=this.getArticleAmountInput_();
    return (tmp)?tmp.value():undefined;
};

[更新]

问题是,当我添加一个typedef时,我会收到myapp.dom is never defined的警告,但当我让代码确定类型是什么时,我会Bad type annotation.

尝试添加类似的typedef:

/**
 * @typedef {{getArticleAmount:function(this:myapp.dom):?number}}
 */
myapp.dom;

但是不要真正理解为什么goog.provide应该创建myapp.dom并且编译器应该知道。

[更新]

我从构造函数创建了以下myapp.workflow。现在编译器应该识别类型,Eclipse可以编写代码辅助。不确定这是否可行,但我会尝试重新考虑一个小项目。

在types.js中设置主要类型

// source: js/mmyapp/types.js
goog.provide("myapp.types");
/** @constructor */
var gooblediegoog=function(){};
/** @constructor */
gooblediegoog.prototype.WorkFlow=function(){};
/** @constructor */
gooblediegoog.prototype.Dom=function(){};
myapp.types=new gooblediegoog();

我的代码中根本没有使用的文件,但告诉Eclipse如何自动完成:

// source: js/myapp/forCodeAssist.js
/** @const {boolean} */
var ALLWAYSFALSE=false;

if(ALLWAYSFALSE){
    /**needed for Eclipse autocomplete
     * @constructor
     */
    var MyApp=function(){};
    MyApp.prototype.types=new gooblediegoog();
    Window.prototype.myapp=new MyApp();
    MyApp.prototype.workflow=new myapp.types.WorkFlow();
    MyApp.prototype.dom=new myapp.types.Dom();
}

工作流程的实施:

// source: js/myapp/workflow.js
goog.provide("myapp.workflow");
goog.require("myapp.types");
goog.require("myapp.dom");

/** @returns number|undefined */
myapp.types.WorkFlow.prototype.createOrder=function(){
    return myapp.dom.getArticleAmout();
};
myapp.workflow=new myapp.types.WorkFlow();
window['console'].log(myapp.workflow.createOrder());

myapp.workflow.createOrder=...替换为myapp.types.WorkFlow.prototype,删除myapp.workflow并删除myapp.workflow=new myapp.types.WorkFlow(),即可转换为goog.require("myapp.types")语法。如果需要,也许这可以在构建/编译过程中自动化。

我不确定在构造函数的帮助下创建单个对象是否比仅仅goog.require创建myapp.workflow并像以前一样添加属性(并且已经完成)要昂贵得多在封闭库中。)

1 个答案:

答案 0 :(得分:1)

匿名类型(名称空间或单例)在Closure-compiler中没有特定类型,不能在注释中用作类型名称。只有构造函数和接口可以用作新的类型名称。 (可以使用typedef,但实际上只是简写注释)

在许多情况下,编译器将正确推断类型,您不需要对其进行注释。在您的具体情况下,问题是您使用this关键字。在静态对象/命名空间中使用this关键字是危险的,不受支持。编译器将发出警告。虽然您可以使用@this注释来取消警告,但这不是正确的操作,因为您没有使用this.call专门指定.apply引用。< / p>

解决方案是使用完整的对象名称:

/**
 * Gets the article amount input value
 */
mycompany.myapp.dom.getArticleAmount=function(){
  var tmp=mycompany.myapp.dom.getArticleAmountInput_();
  return (tmp)?tmp.value():undefined;
};

有关完整的技术详情,请参阅This this is your this帖子。