2012-06-24 4 views
2

J'utilise un modèle de conception qui utilise l'instruction return pour exposer les méthodes de classe publique.Google Closure Compiler, comment gérer JSC_INEXISTENT_PROPERTY avec élégance?

problème est: Je reçois beaucoup des avertissements JSC_INEXISTENT_PROPERTY en mode avancé de fermeture du compilateur, ce qui rend difficile de vérifier les mises en garde qui comptent réellement.

Exemple de modèle que j'utilise:

// ==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'); 

Avertissements:

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

sortie (formaté):

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

Ce qui est bizarre, parce que la fermeture compris ce que le code a été faire et compilé le code correctement, en renommant myPublicFunc systématiquement à a. Alors pourquoi ai-je reçu cet avertissement? Est-ce que je fais quelque chose de mal? Remarque: Je ne souhaite pas désactiver ces avertissements car ils masqueraient également les avertissements dont je me soucie réellement. Je ne veux pas non plus utiliser des chaînes entre guillemets ou des exports car je veux que Closure les compresse.

Répondre

4

Votre fonction est annotés de manière incorrecte. Il est en fait pas un constructeur et dans ce cas, le mot-clé new .. Votre fonction est inutile retourne simplement un type anonyme avec une propriété myPublicFunc

Pour annoter un tel modèle, vous pouvez utiliser le type d'enregistrement:

/** @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'); 

Une autre option d'annotation consiste à créer une interface et à transtyper l'objet renvoyé pour qu'il devienne cette interface. Cette option serait utile lorsque plusieurs fonctions renvoient un objet conforme à la même interface.

1

Ajout

MyClass.prototype.myPublicFunc = null; 

résoudrait le problème que je ne sais pas si cela est la meilleure solution. Je ne sais pas vraiment comment le compilateur fonctionne, mais j'imagine que si vous avez une fonction constructeur, il s'attend à ce que les propriétés de l'instance soient affectées à this dans le constructeur ou à MyClass.prototype.

Si vous supprimez l'annotation @constructor et omettez new, alors il est un avertissement non (mais le code compilé est que console.log("Hello World");.

3

Vous pouvez également utiliser:

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

La fonction peut être appelée à « nouveau », mais ne renvoie pas une instance de « MyClass ».

+0

L'utilisation de la nouvelle annotation avec le type d'enregistrement génère une erreur "Bad type annotation" lorsque je la teste. –

+0

c'est dommage, nous devrions le réparer. – John

+1

Cela fonctionne avec un typedef. –

Questions connexes