There are a couple places in the Closure library where interfaces have an addImplementation/isImplementedBy
pair of functions to do runtime type checking on the interface (similar to this answer). I'm not entirely a fan of this solution where I have something very simple. Is there any way to do duck typing with ADVANCED_OPTIMIZATIONS enabled? Say I have an interface, and a component that takes special action on children with that interface, e.g.:
/** @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 consistently rename that "doSomething" property with the implementations? If not, will adding a type union ensure that it will? e.g.
/**
* @param {goog.ui.Component|MyInterface} child
*/
MyComponent.prototype.addChild = function( child, opt_render) {
if (child.doSomething) {
child.doSomething();
}
};
This is what @record
was added for. You'll need to be using a pretty recent version of the compiler to make use of it (something dated at least 2016).
Just replace @interface
with @record
and you should get the behavior you desire. The compiler will rename things consistently.