How to pick between inheritance, `implements`, and `partial interface` in a spec?


#1

WebIDL provides 3 ways to say that a set of members listed in one place appears on an interface defined in another place:

Inheritance:

interface SomeMembers {
  DOMString getStuff();
};
interface DefinedElsewhere : SomeMembers {};

implements:

interface MoreMembers {
  long otherStuff();
};
DefinedElsewhere implements MoreMembers;

partial interface:

partial interface DefinedElsewhere {
  Promise<void> yetAnotherMember();
}

It’s not clear to me how to decide which of these to use in any given situation. Here’s what I have so far:

  1. Inheritance leads to a JavaScript prototype chain, which might cost time in each call, but might save space if the base class is inherited from many times.
  2. It’s only possible to inherit from a single other interface, so this doesn’t scale if you want to pull members from several other places.
  3. A partial interface doesn’t work well if you have several related methods you want to put in multiple places. For example, you’d have to list methods twice to add them to both Window and WorkerGlobalScope with a partial interface, but you could write that list just once if you added them with implements.
  4. implements makes you come up with a name for the implemented interface, which partial interface doesn’t.

These seem to add up to the following guidelines:

  1. Use partial interface when you’re adding fields to only 1 interface, or you’re adding only 1 simple field to multiple interfaces.
  2. Use implements otherwise.

What all am I missing?

Does anyone have better guidelines?


#2

Nope, those are the guidelines I follow pretty much exclusively. partial for extending one, implements for creating “base” functionality to be used by several. Don’t use inheritance unless you really mean it; it’s not a mixin tool.