Improving API documentation in TypeScript (Part 1)

The JavaScript and TypeScript ecosystems represent the largest community of software developers working professionally today.[1] The prevailing package repository, npm, is the largest such registry for any language.[2] While I’d prefer to say authors of TypeScript packages enjoy similarly-mature tools for writing and sharing API documentation, the real situation is more complicated.

In this article I’ll discuss gaps in current documentation tools for TypeScript libraries, and where I hope the TypeScript ecosystem might go from here.

What is API documentation?

API documentation is reference material helping other software developers use a software library. Libraries evolve over time, so it’s common to write documentation in source files alongside code, as comments in JSDoc or TSDoc syntax. In addition to handwritten explanations, API references generally include technical details (property types, method signatures, …) of the library’s API, which can be inferred from the source code by tooling.

In smaller projects, API documentation may be contained in a single Markdown file. In larger projects, documentation may require a complete website, which often becomes both more complex to maintain and more necessary to onboard new users and contributors.

What is an API model?

API models are declarative representations of the public surfaces (classes, methods, properties, …) in a library. The model provides information about parameters and return types, without any dependency on the internal implementation.

Given a simple TypeScript function,

function createWidget(widgetType: string, gizmoCount = 4): Widget {
  // ...
}

… a hypothetical API model might look like this:

{
  name: 'createWidget'
    params: [
        {name: 'widgetType', type: 'string'},
        {name: 'gizmoCount', type: 'number', optional: true, defaultValue: 4}
    ],
    returns: {type: 'Widget'}
}

API models for a full library will be considerably more complex, but can be subdivided into chunks like the one above, and formatted as HTML or Markdown.

What’s missing

Existing TypeScript documentation tools[3] [4] [5] share two fundamental limitations.

  1. No standard, stable, serializable, and type-safe representation of an API model exists.
  2. Without such an API model, mature and flexible formatting tools cannot exist.

TypeScript needs a representation of an API model that is type-safe and semantically versioned. The model should provide enough information to render formatted API documentation with simple templates, and should allow a developer to “bring your own framework”, without being tied to a particular web stack.

Creating such an API model doesn’t necessarily mean throwing out current tools — parsing TypeScript code to construct an API model is pretty complicated. While they don’t offer this today, existing projects like API Extractor or TypeDoc might be used to produce a generic API model with these characteristics.

But it’s unrealistic to expect maintainers of projects like API Extractor and TypeDoc to produce formatting tools compatible with many web frameworks. Add requirements of flexible styling for small and large projects, and that’s an open-ended, ecosystem-sized task. Without a stable API model that independent projects can depend on, it’s not going to happen.

This wishlist could go on. Documentation appearing alongside source code in GitHub and GitLab repositories. Better integrations with IDEs and commandlines . Internationalization (i18n) support for libraries with global communities. Live examples running alongside API documentation. These are not impossible goals today, but they’re much harder than they need to be.

Next steps

TypeScript needs better ways to represent packaged APIs. Those could be built on existing tools, like API Extractor. From there, adding API documentation into websites built and deployed with [your favorite web framework] becomes a whole lot easier.

I have ideas about where to go from here, but it’s a large project and I’d love to hear from others: Does this describe your experience with TypeScript API documentation? Have I missed anything important about the problem? Would you like to be involved?

Reach out, or look for Part 2 in a future post.


1 Source: Stack Overflow Developer Survey, 2022.

2 Source: State of the Union: npm, 2017.

3 TypeDoc: The generated JSON API model seems intended for use by the theming system (untyped; built on Handlebars), and available themes are a mixed bag. Moreover, I’ve experienced serious quality control issues here. The project began in 2014 and remains pre-1.0.0, maintained on weekends and without any obvious financial sponsorship (which I think it both needs and deserves). TypeDoc is the most popular tool for documentation in TypeScript, but it’s not easy to recommend without adding major caveats.

4 documentation.js: I’ve enjoyed using documentation.js for smaller JavaScript libraries, and would fully recommend it in that context. However, its TypeScript support is not really advertised, and appears to be limited to JavaScript-compatible constructs: no generics, type aliases, etc.

5 API Extractor: Part of Microsoft’s Rush Stack, API Extractor is the “heavy artillery” on this list. Though more difficult to configure than others, it appears well designed and well maintained. The API model (packaged separately as @microsoft/api-extractor-model) is mostly a 1:1 reflection of the source code, and would require further processing to use in an HTML template. Inherited members and generics are not resolved on child classes, for example, and JSDoc comments are unparsed. HTML formatting is mostly left as an exercise left to the reader. Still, the extractor and other components would be great foundations for other tools.