flatline flatline - 7 months ago 19
Javascript Question

Detecting interfaces and duck typing in Closure

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();
}
};




Answer

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.