我一直收到上面提到的警告,但无法弄清楚原因。我添加了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并像以前一样添加属性(并且已经完成)要昂贵得多在封闭库中。)
答案 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帖子。