Typedoc
Overview
Our TypeDoc-based parser combines JSDoc comments with TypeScript types to create documentation that matches what you'd see in modern IDEs. This ensures consistent, high-quality type information whether you're viewing it in your development environment or on our documentation sites.
Consider the following example:
export type WeightUnit = "kg" | "lb"/*** @public*/export interface Dog {/*** The age of the dog in human years.*/age: number/*** The breed of the dog.*/breed?: string/*** The name of the dog.*/name: string/*** The weight of the dog. Refer to {@link weightUnit} for unit type information.*/weight?: number/*** The unit type of the {@link weight} field.** @option `'kg'`: kilograms.* @option `'lb'`: pounds.*/weightUnit?: WeightUnit}
Our parser uses Typedoc to consume your package's exports. It produces a JSON model with compiled type definitions. We reference the interface's name in our TypeDocProps
UI component to render its property documentation table:
<TypeDocProps name="Dog" />
If you've seen QUI documentation before, this table should look familiar.
Name & Description | Option(s) | Default |
---|---|---|
age * The age of the dog in human years. |
| |
name * The name of the dog. |
| |
The breed of the dog. |
| |
The weight of the dog. Refer to weightUnit for unit type information. |
| |
The unit type of the weight field. |
|
age
*
Type
number
Description
The age of the dog in human years.
name
*
Type
string
Description
The name of the dog.
Type
string
Description
The breed of the dog.
Type
number
Description
The weight of the dog. Refer to weightUnit for unit type information.
Type
'kg' | 'lb'
Description
The unit type of the weight field.
Features
Our type parser recursively expands type details, including references, so your type documentation is easy to consume. Here are the features:
- JSDoc tag and comment parsing.
- Property linking to other fields from the same interface.
- Union expansion.
- Reference type resolution.
- Property anchor links, including same-page collision resolution.
- Pretty type formatting.
- Required/deprecated property indicators.
- Mobile-first UI components.
Getting Started
Install Packages
npm i --save-dev @qui/typedoc
yarn add -D @qui/typedoc
pnpm add -D @qui/typedoc
Initialize the config
Run the command and follow the prompts to generate the config:
qui-typedoc init
Entry Points
entryPoints
refer to the root files or directories from which Typedoc will begin the documentation generation process. These are automatically inferred from your tsconfig
file's includes
and files
fields.
You may optionally define entryPoints
in the typedoc configuration file.
QUI Typedoc config
// qui-typedoc.config.tsimport {BuildOptions} from "@qui/typedoc"export default {// ...typedocOptions: {// optional. If omitted, the entryPoints will be inferred from// the tsconfig's `includes` and `files` fields.entryPoints: ["./dist/index.d.ts"],tsconfig: "tsconfig.typedoc.json",},} satisfies BuildOptions
Typedoc tsconfig
// tsconfig.typedoc.json{"compilerOptions": {// ...},"include": ["./dist"]}
Multiple Entry Points
If your library has a local dependency on another package in your workspace, you will need to list that package in your project's entryPoints. Let's illustrate this scenario with an example.
Consider an example project with the following project structure:
packages
base
react
react-docs
- Assume that
react
has a dependency onbase
. - Both the
react
andbase
projects compile types to their project'sdist
folder. react-docs
contains the@qui/typedoc
configuration.
The tsconfig needs to account for both modules:
// packages/react-docs/tsconfig.typedoc.json{"compilerOptions": {// ...},"include": ["../base/dist", "../react/dist"]}
If you're specifying entryPoints in the typedoc config, you will also need to account for each module.
External Reference Types
Types from external modules aren't compiled by default. To include external types, you'll need to do two things:
1. Modify your tsconfig to include the path to the external module's compiled types.
// tsconfig.typedoc.json{"compilerOptions": {// ...},"include": ["./dist", "node_modules/<external-package-name>/dist"]}
2. Enable external module parsing in the typedoc configuration:
// qui-typedoc.config.tsimport {BuildOptions} from "@qui/typedoc"export default {// ...typedocOptions: {// this is `true` by defaultexcludeExternals: false,tsconfig: "tsconfig.typedoc.json",},} satisfies BuildOptions
Recommendations and Known Issues
- We recommend that you point typedoc at the compiled TypeScript types to improve compilation time. This is why we point our entryPoints at files in
dist
. - For Angular packages, the output types strip away necessary type information, so we target the package's src root instead, i.e.
./src/index.ts
. - Sometimes it is desirable to prevent the expansion of deeply nested types, like an interface that recursively references itself. We've enhanced the @inheritDoc tag for this purpose. Refer to the JSDoc Tags section to learn more.
Reference Types
Ensure References are Exported for Full Expansion
Type definitions (like interfaces or type aliases) used by exported members won't be fully expanded if they're not exported themselves. Consider this example:
interface InternalDefinition {/*** Some function*/someFn: (args: string) => void}/*** @public*/export interface ExternalDefinition {/*** Property*/property: InternalDefinition}
- In this scenario, because
InternalDefinition
is not exported, the documentation generated forExternalDefinition.property
will only display the type nameInternalDefinition
. - Our tool relies on TypeDoc's analysis of the public API, and unexported types are treated as internal implementation details. To ensure the detailed structure (e.g.,
{ someFn: (args: string) => void }
) is shown, you must also export theInternalDefinition
interface.
JSDoc Tags
The following tags are enhanced with functionality in the UI.
@default
Use the @default
tag to indicate a default value for a property.
/*** @public*/export interface DefaultTagExample {/*** Example property.** @default 0*/age?: number}
@inheritDoc
/*** @public*/export interface Option {/*** Unique identifier for the option.*/id: string/*** Nested options.** @inheritDoc*/options?: Option[]/*** Option value.*/value: string}
@link
Context is applied conditionally to the inline @link
tag.
- If the link starts with
https
, it's treated as an external link. - If the tag refers to a named property, it's treated as an internal link.
/*** @public*/export interface LinkExample {/*** Visit {@link https://google.com this external link} to learn more.*/externalLink?: string/*** Refer to the {@link externalLink} property.*/internalLink?: string}
Name & Description | Option(s) | Default |
---|---|---|
Visit this external link to learn more. |
| |
Refer to the externalLink property. |
|
Type
string
Description
Visit this external link to learn more.
Type
string
Description
Refer to the externalLink property.
@option
Renders a bullet list entry for each option. Useful for documenting union or enum types.
export type WeightUnit = "kg" | "lb"/*** @public*/export interface OptionTagExample {/*** The unit type of the weight field.** @option `'kg'`: kilograms.* @option `'lb'`: pounds.*/weightUnit: WeightUnit}
Name & Description | Option(s) | Default |
---|---|---|
The unit type of the weight field. |
|
Type
'kg' | 'lb'
Description
The unit type of the weight field.
@see
Use the @see
tag to render a separate section of documentation in the JSDoc comment. This is typically used to highlight related types or interfaces.
/*** @public*/export interface SeeTagExample {/*** @see {@link someOtherPropExample}*/otherPropExample?: string/*** Another prop.*/someOtherPropExample?: string}
Name & Description | Option(s) | Default |
---|---|---|
| ||
Another prop. |
|
Type
string
Description
Related symbols
Type
string
Description
Another prop.
@since
The @since
tag is used to indicate when a property was added. The default configuration assumes that you have a changelog at /changelog
, but this can be modified per instance of TypeDocProps
using the changelogPathname
prop:
<TypeDocProps changelogPathname="/changelogs/mdx-docs" name="SinceExample" />
/*** @public*/export interface SinceExample {/*** Foo.** @since 3.10.0*/foo: string}
Typedoc Configuration
Default Options
This module ships with reasonable defaults that enable efficient yet comprehensive TypeScript module documentation. You can override these defaults with the typedocOptions
config property.
Refer to the corresponding Typedoc documentation for details about each property.
export const defaultOptions: Partial<TypeDocOptions> = {entryPointStrategy: "expand",// custom categories that we set to exclude specific properties or interfaces.excludeCategories: ["react-dom"],excludeExternals: true,excludeInternal: true,excludeNotDocumented: true,excludeNotDocumentedKinds: ["Module","Namespace","Enum","Variable","Function","Class","Constructor","Property","Method","CallSignature","IndexSignature","ConstructorSignature","Accessor","GetSignature","SetSignature","Reference",],excludePrivate: true,excludeProtected: true,logLevel: "Error",readme: "none",}