dx-spec
dx-spec copied to clipboard
Documenting overloaded methods
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?
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() {
// ...
}
}
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
@anandthakker Yeah that's correct for standalone functions (except for in type declaration files)