2016-03-18 2 views
1

Es gibt einige Stellen in der Closure-Bibliothek, in denen Schnittstellen ein addImplementation/isImplementedBy Paar von Funktionen haben, um eine Laufzeitprüfung an der Schnittstelle durchzuführen (ähnlich wie this answer). Ich bin nicht ganz ein Fan dieser Lösung, wo ich etwas sehr einfaches habe. Gibt es eine Möglichkeit, Ententipp mit aktivierten ADVANCED_OPTIMIZATIONS zu tun? Sagen, ich habe eine Schnittstelle, und eine Komponente, die auf Kinder mit dieser Schnittstelle, z.B .:Erkennen von Schnittstellen und Eingabe von Enten Closure

/** @interface */ 
 
MyInterface = function() {}; 
 

 
MyInterface.prototype.doSomething = function() {}; 
 

 
/** 
 
* @constructor 
 
* @extends {goog.ui.Component} 
 
*/ 
 
MyComponent = function() { 
 
    ... 
 
}; 
 

 
/** @inheritDoc */ 
 
MyComponent.prototype.addChild = function(child, opt_render) { 
 
    goog.base(this, 'addChild', child, opt_render); 
 
    if (child.doSomething) { 
 
    child.doSomething(); 
 
    } 
 
};

Will ADVANCED_OPTIMIZATIONS konsequent umbenennen, dass „doSomething“ Eigenschaft mit den Implementierungen besondere Aktion nimmt? Wenn nicht, wird das Hinzufügen einer Typ-Union sicherstellen, dass es geht? z.B.

/** 
 
* @param {goog.ui.Component|MyInterface} child 
 
*/ 
 
MyComponent.prototype.addChild = function(child, opt_render) { 
 
    if (child.doSomething) { 
 
    child.doSomething(); 
 
    } 
 
};

Antwort

2

Dies ist, was @record für zugegeben wurde. Sie müssen eine ziemlich neue Version des Compilers verwenden, um es zu verwenden (etwas, das mindestens bis 2016 datiert ist).

Ersetzen Sie einfach @interface durch @record und Sie sollten das gewünschte Verhalten erhalten. Der Compiler wird die Dinge konsistent umbenennen.

+0

Danke, ich wusste nicht über @ Record, es sieht in der Regel sehr nützlich. Im Falle der Typeinschränkung, die ich hier mache, bin ich mir nicht sicher, ob es etwas hinzufügt - ich möchte immer noch nach einer impliziten Schnittstelle suchen. Ich erkannte nach dem ersten Post, dass ich die Variable einfach auf die Schnittstelle tippen und dann nach der Eigenschaft suchen kann - funktioniert das nur mit '@ record' oder wird es immer noch mit' @ interface' funktionieren? – flatline

+2

Ein Objekt wird nicht mit einer Schnittstelle übereinstimmen, ohne dass eine explizite Anmerkung "@ implements" vorhanden ist. Es passt einen Datensatz einfach durch eine passende Signatur an. Sie werden weiterhin Ihren Union-Typ benötigen, um der 'addChild'-Methode mitzuteilen, dass die Schnittstelle übergeben werden kann. –

1

Ich habe die Antwort von Chad als die Lösung verlassen, aber ich habe es wieder gelesen, nachdem ich die Kompilierung begonnen habe und der Nachwelt eine ausführlichere Antwort für den allgemeinen Fall der Entensuche veröffentliche.

Sie können dynamischen Downcasting mit ADVANCED Optimierungen führen auf wie folgt:

var maybeRecordType = /** @type {MyRecordType} */ (someObject); 
if (maybeRecordType.propertyInQuestion) { 
    maybeRecordType.propertyInQuestion(); 
} 

Sie kompilieren Zeit verlieren Kontrollen auf diese Weise offensichtlich, wenn es Kollisionen auf dem Eigenschaftsnamen zwischen zwei möglichen Arten geführt wird, aber das ist immer ein Risiko bei der Ente tippen.

Verwandte Themen