This chapter describes how to document TypeScript APIs via doc comments (multi-line comments whose contents follow a standard format). We will use the npm-installable command line tool TypeDoc for this task.
The de-facto standard for documenting APIs in JavaScript are JSDoc comments (which were inspired by Javadoc comments). They are multi-line comments where the opening delimiter is followed by a second asterisk:
/**
* Adds two numbers
*
* @param {number} x - The first operand
* @param {number} y - The second operand
* @returns {number} The sum of both operands
*/
function add(x: number, y: number): number {
return x + y;
}
The hyphen after parameter names such as x is optional.
TypeScript itself supports JSDoc comments as a way to specify types in plain JavaScript code (more information).
TSDoc adapts JSDoc comments so that they are a better fit for TypeScript – e.g., types in comments are not allowed and the hyphen is mandatory:
/**
* Adds two numbers
*
* @param x - The first operand
* @param y - The second operand
* @returns The sum of both operands
*/
function add(x: number, y: number): number {
return x + y;
}
The API documentation generator TypeDoc uses doc comments to generate HTML API documentation. TSDoc comments are preferred, but JSDoc comments are supported, too. TypeDoc’s features include:
We can use the following package.json script to convert TSDoc comments to API documentation:
"scripts": {
"\n========== TypeDoc ==========": "",
"api": "shx rm -rf docs/api/ && typedoc --out docs/api/ --readme none
--entryPoints src --entryPointStrategy expand --exclude '**/*_test.ts'",
},
The entry for "api" is a single line; I have broken it up so that it can be displayed better.
As a complementary measure, we can serve GitHub pages from docs/:
my-package/docs/api/index.html
robin): https://robin.github.io/my-package/api/index.html
You can check out the API docs for @rauschma/helpers online (warning: still underdocumented).
Since version 0.27.7, TypeDoc lets us refer to parts of external files via the doc tag {@includeCode}:
File util.ts:
/**
* {@includeCode ./util_test.ts#utilFunc}
*/
function utilFunc(): void {}
Note the hash (#) and the name utilFunc after the path of the file: It refers to a region inside util_test.ts. A region is a way to mark sequences of lines in a source file via comments. Regions are also supported by Visual Studio Code where they can be folded (documentation).
This is what the region inside util_test.ts looks like:
test('utilFunc', () => {
//#region utilFunc
// ...
//#endregion utilFunc
});
The file names already suggest the use case for this feature: It enables us to publish documentation where all code examples (such as region utilFunc) are tested.
In the past, TypeDoc only let us include full files, which meant one file per example – with test boilerplate showing up in the documentation.
File array.ts:
/**
* Split `arr` into chunks with length `chunkLen` and return them
* in an Array.
* {@includeCode ./array_test.ts#arrayToChunks}
*/
export function arrayToChunks<T>(
arr: Array<T>, chunkLen: number
): Array<Array<T>> {
// ···
}
File array_test.ts:
// ···
test('arrayToChunks', () => {
//#region arrayToChunks
const arr = ['a', 'b', 'c', 'd'];
assert.deepEqual(
arrayToChunks(arr, 1),
[['a'], ['b'], ['c'], ['d']],
);
//#endregion arrayToChunks
assert.deepEqual(
arrayToChunks(arr, 2),
[['a', 'b'], ['c', 'd']],
);
});
{@includeCode}