Description
- I have checked issues with enhancement label and found no duplicates
Problem
It's not currently possible to use typedoc's type to string rendering alone — you get the CLI, the file/filesystem handling, markdown rendering & syntax highlighting, etc. Extracting string rendering to a separate module/package would enable:
- using typedoc in a more modular fashion, i.e. to parse and render independent of one another
- use of parts of typedoc's capabilities in more areas, such as browser-like environments or other site generators
- rendering of type classes as is possible now, but also of serialized objects like the ones in typedoc JSON outputs
My driving use case is to render types to documentation in Docusaurus v2, which uses React & MDX. While there is an existing plugin for outputting markdown and targeting Docusaurus v2, it doesn't allow using the full power of the React & MDX ecosystems (it just outputs static markdown).
Suggested Solution
I'd be willing to work on this if accepted. I recommend extracting the toString
methods that currently live in each of typedoc's various type classes into a separate module that can then be used internally as well as exposed to allow the above mentioned features. The new API would act on objects provided as arguments which should allow it to support both the existing functionality and also operate on data such as from typedoc's serialized JSON output.
I imagine at a high level that the API could look something like this:
// specialized functions for each type
export const stringifyArray = (node: ArrayType): string => {
// implementation
};
export const stringifyUnion = (node: UnionType): string => {
// implementation
};
const stringifiers = {
array: stringifyArray,
union: stringifyUnion
// ...
};
// generic type-to-string renderer that defers to
// the appropriate specialized functions above
export const stringifyType = (node: Type | SerializedType): string => {
return stringifiers[node.type](node);
};
Then the existing classes could likely be refactored to use these by implementing toString
in the base class instead of overriding it in every subclass:
// src/lib/models/types/abstract.ts
import { stringifyType } from '../path/to/stringify-module'
export abstract class Type {
// ...
/**
* Return a string representation of this type.
*/
toString(): string {
return stringifyType(this);
}
}