Open Oblarg opened 1 week ago
After a few hours looking into this... producing the type of documentation you're looking for is ridiculously painful. In an ideal world, Topic.on
in the last example would be documented as if it was written:
function topic(eventType: "bar", (event: Bar & { topic: "topic" }) => void): void;
function topic(eventType: "baz", (event: Baz & { topic: "topic" }) => void): void;
// ...
... or in some cases, inlining even further as:
function topic(eventType: "bar", (event: { type: "bar", topic: "topic" }) => void): void;
function topic(eventType: "baz", (event: { type: "baz", topic: "topic" }) => void): void;
// ...
Note: This assumes that on
should be declared as the following, with a generic constraint that can be used to enumerate the possible signatures.
export function on<EventType extends Topic.Event["type"]>(
eventType: EventType,
handler: Handler<EventType, Event>,
) {}
There are a few problems with this, including:
TypeScript does not export the necessary functions to be able to perform this surgery. TypeDoc needs to ask TypeScript to instantiate type aliases with each member of the type parameter constraint. (really, a plugin, there's no chance of this ever being built in, way too nasty)
The necessary function is getTypeAliasInstantiation
in the type checker. Using patch-package
to add it isn't that much code.
Even using the type returned by getTypeAliasInstantiation
, TypeScript doesn't eagerly evaluate the alias, so TypeDoc ends up converting it as Handler<"foo", Events>
. 6b9360f adds an @inline
tag that can be placed on Handler
to make TypeDoc do what you want (shipping in 0.27)... mostly, with the limitation that it doesn't work when TypeDoc is converting with type nodes (rather than types, they are used for functions outside classes and type aliases today, I might change it just be type aliases, don't remember why it works like that today...), it doesn't respect @inline
if there are type arguments.
... all that said, https://github.com/Gerrit0/typedoc-plugin-generic-signature-overloads exists now, and produces this output, in a horrible hacky way:
Woah! Thanks a ton for the work here, this is awesome. Not too surprised the implementation is a pain, but the output here is great.
Search Terms
events, type inference, discriminated unions, mapped types
Problem
Documenting a typed event bus is difficult in TypeDoc. If our event binding method is genericized to dynamically type the payload argument in a correct manner, at best we get a long list of string keys for our events, but no real way to view the payloads matching each event key:
A simple reproduction case (with several levels of type complexity) can be found in this typescript playground.
Suggested Solution
There should be some way to either render inline or link to an appropriate expansion/flattening of the corresponding event payload types alongside the string key values.