tmcw / dx-spec

Issue (and spec) repository for the development of a spec that would succeed JSDoc.
27 stars 0 forks source link

Documenting overloaded methods #5

Open tmcw opened 6 years ago

tmcw commented 6 years ago

Overloading methods is often an anti-pattern: monomorphism has performance advantages, and often multiple functions taking different arguments are more clear than one function that accepts a variety of arguments.

That said! There are plenty of usecase for functions with more than one signature. For instance, d3 has the pattern of:

arc.innerRadius(value) -> arc
arc.innerRadius() -> value

The most literal JSDoc'y way to express this would be:

arc.innerRadius(value?) -> (arc | value)

Which is not very informative! The function knows that either the input is nil and the output is x or the input is x and the output is self. There's no case in which the signature is actually

arc.innerRadius(value) -> value

That doesn't happen.


In documentation.js, we supported/support adding multiple documentation comments in front of the same block of code and thus documenting one thing multiple times. Which is not that cool!

Note that the typescript definition for that polymorphic method defines it thrice - twice for different input types, and once for the no-input case where it returns this.

How would this kind of thing be best documented?

jamiebuilds commented 6 years ago

I think this is a good use case for building on the Flow comment syntax:

class Arc {
  /*::
  // description
  innerRadius: (d: Datum, ...args: any[]) => number;
  // description
  innerRadius: (radius: number) => this;
  // description
  innerRadius: (radius: (d: Datum, ...args: any[]) => number) => this;
  */
  innerRadius() {
    // ...
  }
}
anandthakker commented 6 years ago

Note that in flow, I think the only way to do this for standalone functions is to use an intersection type on a function expression:

const minus: ((number, number) => number) & ((number) => number)) = function(x, y) { return typeof y === 'number' ? x - y : -x; }

AFAIK you can't correctly annotate a function declaration (function minus() {}) with multiple signatures

jamiebuilds commented 6 years ago

@anandthakker Yeah that's correct for standalone functions (except for in type declaration files)