Skip to content

[RFC] Consider extracting toString functionality to standalone module #1160

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
1 task done
haltcase opened this issue Jan 12, 2020 · 4 comments
Closed
1 task done
Labels
discussion Discussion on large effort changes to TypeDoc

Comments

@haltcase
Copy link

haltcase commented Jan 12, 2020

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);
    }
}
@Gerrit0
Copy link
Collaborator

Gerrit0 commented Jan 13, 2020

Thanks for taking the time to write this out for discussion.

I think factoring out the conversion from a TypeScript project to models into a new module that TypeDoc consumes would be beneficial in forcing us to design an API that is actually usable for consumers. #439 was an attempt at this several years ago, but ended up just getting neglected since there wasn't enough time to get it reviewed + merged.

The toString functionality is currently somewhat of an afterthought. When outputting a type it isn't very useful for generating HTML or JSON to just output the type as a string. For HTML, the parts of the type that refer to other reflections should be hyperlinked, and for JSON it should be broken into parts so that the consumer can do the same when consuming the JSON...

Right now we offer very little support for consumers of the JSON format. There are several interfaces that describe the resulting type, but no easy way to consume it. This would be a step in the right direction, and the described solution makes sense to me.


(not to put a damper on this effort but...)

If you want toString functionality, why consume the JSON in the first place? It is fairly straightforward to get a ProjectReflection describing the converted project, which provides the toString functionality in addition to several other helper methods. Is there some reason to use the JSON instead of this?

@haltcase
Copy link
Author

@Gerrit0 For my Docusaurus use case, I wasn't able to figure out a way to use the API where it could process the files (server side) and also pass that data to the renderer (client side). The client is also unable to use things like Node's fs module.

@Gerrit0
Copy link
Collaborator

Gerrit0 commented Jan 13, 2020

Ah, that makes sense. 👍

haltcase added a commit to haltcase/typedoc that referenced this issue Feb 22, 2020
@Gerrit0 Gerrit0 added the discussion Discussion on large effort changes to TypeDoc label Nov 28, 2020
@Gerrit0
Copy link
Collaborator

Gerrit0 commented Sep 4, 2023

Eventually I want to make it possible to use TypeDoc from a browser, that's so far away, and so low down on the priority, list, however, that it's likely not going to happen...

@Gerrit0 Gerrit0 closed this as not planned Won't fix, can't repro, duplicate, stale Sep 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion Discussion on large effort changes to TypeDoc
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants