Search code examples
javascriptgoogle-closure-compilergoogle-closure

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


Solution

  • 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.