Google Closure Compiler, how to handle JSC_INEXISTENT_PROPERTY gracefully?

十年热恋 提交于 2020-01-02 11:00:19

问题


I'm using a design pattern that uses the return statement to expose public class methods.

Problem is: I'm getting a lot of JSC_INEXISTENT_PROPERTY warnings in Closure Compiler's Advanced mode, which makes it difficult to check the warnings that actually matter.

Example of the pattern I use:

// ==ClosureCompiler==
// @compilation_level ADVANCED_OPTIMIZATIONS
// ==/ClosureCompiler==

/**
 * @constructor
 */
var MyClass = function() {

    var someFunc = function(myString) {
        console.log(myString);
    }

    return {
        myPublicFunc: someFunc
    };
}

var myClassInstance = new MyClass();
myClassInstance.myPublicFunc('Hello World');

Warnings:

JSC_INEXISTENT_PROPERTY: Property myPublicFunc never defined on MyClass \
    at line 16 character 0
myClassInstance.myPublicFunc('Hello World');

Output (formatted):

(new function() {
    return {
        a: function(a) {
            console.log(a)
        }
    }
}).a("Hello World");

Which is weird, because Closure understood what the code was doing and compiled the code correctly, renaming myPublicFunc consistently to a. So why did I get this warning? Am I doing something wrong?

Note: I do not want to turn off these warnings because it would also hide warnings I actually care about. I also do not want to use quoted strings or exports because I do want Closure to compress these.


回答1:


Your function is annotated incorrectly. It's actually not a constructor and in this case the new keyword is unnecessary. Your function simply returns an anonymous type with a myPublicFunc property.

To annotate such a pattern, you would use the record type:

/** @return {{myPublicFunc: function(string) }} */
var MyClass = function() {

    var someFunc = function(myString) {
        console.log(myString);
    }

    return {
        myPublicFunc: someFunc
    };
};

var myClassInstance = MyClass(); // new keyword not needed
myClassInstance.myPublicFunc('Hello World');

Another annotation option is to create an interface and type-cast the returned object to be that interface. This option would be useful when multiple functions return an object that conforms to the same interface.




回答2:


You can also use:

/** @type {function(new:{myPublicFunc: function(string)} )} */
var MyClass = function() {...

The function can be called with "new" but doesn't return an instance of "MyClass".




回答3:


Adding

MyClass.prototype.myPublicFunc = null;

would solve the problem though I don't know whether this is the best solution.

I don't really know how the compiler works, but I could imagine that if you have a constructor function, it expects instance properties to be assigned to this inside the constructor or to MyClass.prototype.

If you remove the @constructor annotation and omit new, then there is not warning (but the compiled code is only console.log("Hello World");.



来源:https://stackoverflow.com/questions/11178589/google-closure-compiler-how-to-handle-jsc-inexistent-property-gracefully

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!