A TypeDoc plugin that writes the API reference of a TypeScript project, or of a JavaScript one documented with JSDoc, as doc-kit Markdown. doc-kit then builds it into your site next to your hand-written pages: a page per module, namespace and export, with signatures, typed lists, stability indicators and source links.
This plugin is experimental: its output and options may change in any release.
This page is the plugin's reference. Documenting TypeScript walks through it step by step, from a TypeScript or JavaScript project to a built site.
npm install --save-dev typedoc @doc-kit/typedoc
The plugin is built for TypeDoc 0.28. Load it in your TypeDoc configuration, and set where the reference goes:
import { load } from '@doc-kit/typedoc'; export default { plugin: [load], entryPoints: ['src/index.ts'], docKit: 'docs/api', };
docKit is the doc-kit output's shortcut, like TypeDoc's html and json;
outputs: [{ name: 'doc-kit', path: 'docs/api' }] works too. Passing load
rather than the package name lets TypeDoc load the plugin from your project,
which strict package managers such as pnpm keep apart from TypeDoc's own
installation.
Then generate the reference, and point doc-kit at it:
npx typedoc --options typedoc.config.mjs
export default { global: { input: ['docs/**/*.md'] }, metadata: { typeMap: 'docs/api/type-map.json' }, };
The output directory follows TypeDoc's layout:
| File | What it holds |
|---|---|
modules/plugins.md | A page per module and namespace, listing its exports by group |
classes/Watcher.md, functions/build.md, … | A page per exported class, interface, enum, type alias, function and variable |
classes/plugins.BannerPlugin.md | An export of a namespace, or of a module when there are several entry points, prefixed by its name |
interfaces/BuildOptions.input.md | A page per member of the types listed in docKitMemberPages |
type-map.json | Type names mapped to their pages, for doc-kit's metadata.typeMap |
pages.json | Every page, for building your site's navigation |
- With several entry points, each one is a module, so the pages of its exports
are prefixed by its name, the main entry point's included. An entry point
merged into the project with
@mergeModuleWith <project>is the exception: its exports become the project's own. - The project itself gets no page, so the reference's landing page is yours to
write (
docs/api/index.md, for instance). - The plugin doesn't empty the directory before writing, so delete it before regenerating when you remove or rename exports.
- Pages link to each other with relative
.mdlinks, which doc-kit resolves.
Source links point to https://github.com/<repository>/blob/<ref>/<file>.
The file path is relative to TypeDoc's displayBasePath or basePath (or,
without either, the common directory of your sources), so set basePath to
your repository's root and doc-kit's
global.repository
to the repository. On the website, <ref> is
jsx-ast.ref,
'main' by default. External declarations (TypeDoc's externalPattern) get
no source link.
type-map.json maps each class, interface, enum and type alias to its page,
for doc-kit to
link the {Type} annotations
of the reference, and of any other page that names your types. Its paths
start with docKitBasePath and have no extension, so the type
links need a host that serves /api/classes/Watcher from Watcher.html (see
Page URLs).
pages.json lists every page with its name (the full name, such as
plugins.BannerPlugin), kind (Class, Function, …), url (the page path
doc-kit gives it, such as /api/classes/Watcher) and, when you use
@category, its category. Types documented on a member's page (see
docKitMemberPages) are left out.
The url is the form the
website's sidebar links
take.
Building the sidebar
turns the list into sidebar groups.
- Functions, methods, and variables or type aliases of a function type
become doc-kit signatures: a heading such as
watcher.close([force]), with optional parameters in brackets, and a typed list of the parameters and the return value. Each overload gets an entry of its own.- Properties of object parameters are nested in the typed list. Only the first paragraph of a parameter's description goes in the list; the rest follows it.
- A
thisparameter becomes a**Context:**note. Avoidorundefinedreturn gets noReturns:item unless@returnsdescribes it.
- Classes get a
Class:heading, constructors anew Watcher()one, and static methods aStatic method:one. - Members are documented on their type. Static and enum members use its
name (
Watcher.create(),Level.Info), and instance members its name with the first letter lowercased (watcher.close()) or the name set indocKitReceivers. Each member is also anchored by its name alone (#resolveidforresolveId), so links to it survive changes to its signature. Members grouped with@groupget a section per group. - Properties and accessors become entries with a
Type:item. The properties of object types,Partial,ReadonlyandRequiredones included, get entries nested under them. - Events: a class extending
EventEmitter<Events>, or a type whoseon()takes a(...args: Events[E]) => voidlistener, gets anEvent:entry per property ofEvents. Each property is a tuple of the listener's arguments; name its elements ([error: Error, file: string]), since unnamed ones are left out. - Inheritance: classes and interfaces list what they extend in an
Extends:item, and the types extending them in anExtended bynote. - Types: type parameters show their constraint (
keyof EventsforE extends keyof Events), and the parts of a type past TypeDoc'smaxTypeConversionDepthshow asunknown. - Several entry points: the pages of exports the main entry point doesn't
export say which entry points do, by module name (set with
@module). The main entry point is the one merged with@mergeModuleWith <project>, or else the module TypeDoc lists first: the first by name with its defaultsort, or the first entry point whensortEntryPointsisfalse.
@paramand@returnsdescribe the items of the typed list.@deprecatedbecomes a stability indicator of0 - Deprecated, followed by the tag's text, and@experimentalone of1 - Experimental.@defaultand@defaultValueadd a default to theType:or parameter item when they hold a value (a word, a sentence, or a one-line code block). A longer default gets a "Default" section. Parameters without the tag show their declared default.@examplefollows the description, in an "Example" section.@seefollows the description as a "See" line, and@throwsas a**Throws:**one.{@link}and{@linkcode}link to the target's page or entry.- The first sentence of
@summary, or else of the first paragraph, describes an export on its module's page, and a member in the lists linking to its own page. @categorysets the page'scategoryin the page list.- Block tags of your own, declared with TypeDoc's
blockTagsoption, become**Tag:** content. TypeDoc's other block tags, such as@remarksand@since, are left out.
The plugin adds these options to TypeDoc's:
string'docs/api'.
Setting it runs the doc-kit output.stringinput glob starts from (docs for docs/**/*.md). The paths in
the type map and the page list start with it, and its leading and trailing
slashes are ignored. Default: the output directory's name ('api' for
docs/api).null or '' leaves it out. Default: 'type-map.json'.null or '' leaves it out. Default: 'pages.json'.string[]TreeshakeOptions in
boolean | TreeshakeOptions) is documented on that member's page, and links
to the type lead there. Names that match no exported interface or class with
members log a warning. Default: [].Function'interfaces/Plugin'), and its
TypeDoc reflection, and returns the URL to use ('Interface.Plugin'). Links,
the type map and the page list follow it. Set it in a JavaScript
configuration file. Default: undefined.For example, to keep the URLs of a site whose interface pages were at
Interface.<name>:
import { load } from '@doc-kit/typedoc'; export default { plugin: [load], entryPoints: ['src/index.ts'], docKit: 'docs/api', docKitUrlAdapter: url => url.replace(/^interfaces\//, 'Interface.'), };