0

我不断收到上面提到的警告,但不知道为什么。我添加了 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.prototypemyapp.workflow删除myapp.workflow=new myapp.types.WorkFlow()和删除. 转换为语法goog.require("myapp.types")。如果需要,也许这可以在构建/编译过程中自动化。

我不确定在构造函数的帮助下创建单个对象是否比像以前goog.require那样创建 myapp.workflow 并为其添加属性要昂贵得多(并且就像在闭包库中所做的那样)。

4

1 回答 1

1

Anonymous types (namespaces or singletons) don't have specific types in Closure-compiler and cannot be used as a type name in an annotation. Only constructors and interfaces can be used as new type names. (typedefs can be used but are really just shorthand annotations)

In many cases the compiler will correctly infer the types and you will not need to annotate it. In your specific case, it looks like the problem is your use of the this keyword. Using the this keyword in a static object / namespace is dangerous and not supported. The compiler will raise a warning. While you can suppress the warning with a @this annotation, that is not the correct action here as you are not specifically specifying the this reference by using .call or .apply.

The solution is to use the full object name:

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

For the full technical details, reference the This this is your this post.

于 2013-06-14T13:22:42.737 回答