如何使用代码注释:关于JavaScript与TypeScript 注释和文档的自动生成
1. TSDoc:注释规范
TSDoc 是一个标准化 TypeScript 代码中使用的文档注释的建议,以便不同的工具可以提取内容而不会被彼此的标记混淆。
1.1 注释标记简表
注释 | 描述 |
@alpha |
指定 API 项的发布阶段为“alpha”。它旨在用于 第三方开发者最终,但尚未发布。该工具可能会从 公开发布。 |
@beta |
指定 API 项的发布阶段为“测试版”。它已通过实验性发布给第三方开发人员 为了收集反馈。 |
@decorator |
ECMAScript 装饰器有时是一个重要的部分 的 API 协定。但是,今天TypeScript编译器不代表.d.ts输出文件中的装饰器 由 API 使用者使用。该标记提供了一种解决方法,允许将装饰器表达式括起来 在文档评论中。 |
@deprecated |
此块标记表示不再支持 API 项,并且可能会在将来的版本中删除。 标记后跟一个描述推荐替代方案的句子。它递归应用 容器的成员。例如,如果一个类被弃用,那么它的所有成员也是如此。 |
@defaultValue |
如果未显式分配值,则此块标记用于记录字段或属性的默认值。此标记只能与属于 TypeScript class 或 interface 成员的字段或属性一起使用。 |
@eventProperty |
当应用于类或接口属性时,这表示该属性 返回事件处理程序可以附加到的事件对象。事件处理 API 是实现定义的,但通常属性返回类型是一个类 与成员如 addHandler() 和 removeHandler() 。文档工具可以 在“Events”标题下显示此类属性,而不是通常的“Properties”标题。 |
@example |
指示应作为示例演示如何使用 API 的文档部分。 它可能包括代码示例。 |
@experimental |
与 @beta 相同的语义,但由不支持@alpha 发布阶段的工具使用。 |
@inheritDoc |
此内联标记用于通过从另一个 API 项复制 API 项的文档来自动生成该文档 接口项。内联标记参数包含对其他项的引用,该项可能是不相关的类, 甚至是从单独的 NPM 包导入。 |
@internal |
指定不计划由第三方开发人员使用 API 项。该工具可能会修剪 公开发布的声明。在某些实现中,可能允许某些指定的包 使用内部 API 项,例如,因为包是同一产品的组件。 |
@label |
内联 {@label} 标记用于标记声明,以便可以使用 TSDoc 声明引用表示法。 |
@link |
{@link} 内联标记用于创建指向文档系统中其他页面或通用internet URLs的超链接。特别是,它支持引用API项的表达式。 |
@override |
这个修饰符的语义类似于C#或Java中的override关键字。对于成员函数或属性,显式指示此定义重写(即重新定义)从基类继承的定义。基类定义通常会被标记为虚拟的。 |
@packageDocumentation |
用于表示描述整个NPM包的文档注释(相对于属于该包的单个API项)。@packageDocumentation 注释位于 *.d.ts 文件中,该文件充当包的入口点,它应该是在该文件中遇到的第一个/** 注释。包含 @packageDocumentation 标签的注释不应该用于描述单个API项。 |
@param |
用于记录函数参数。@param 标记后面是参数名,后面是连字符,再后面是描述。 |
@privateRemarks |
启动不面向公众的其他文档内容的一部分。 工具必须从 API 参考网站(生成的 *.d.ts 文件)中省略整个部分, 以及包含内容的任何其他输出。 |
@public |
指定 API 项的发布阶段为 “public”。已经正式发布给第三方开发者, 并且其签名保证稳定(例如,遵循语义版本控制规则)。 |
@readonly |
此修饰符标记指示API项应该被记录为只读的,即使TypeScript类型系统可能另有指示。例如,假设一个类属性有一个setter函数,它总是抛出一个异常,说明该属性不能赋值;在这种情况下,可以添加 @readonly 修饰符,以便该属性在文档中显示为只读。 |
@remarks |
API项目的主要文件被分成一个简短的“总结”部分,随后是一个更详细的“备注”部分。在文档网站上,索引页(例如显示类的成员)将只显示简短的摘要,而详细页(例如描述单个成员)将显示摘要,后跟备注。@remarks 块标记结束摘要部分,并开始文档注释的备注部分。 |
@returns |
用于记录函数的返回值。 |
@sealed |
这个修饰符的语义类似于C#或Java中的 sealed 关键字。对于类,指示子类不能从类继承。对于成员函数或属性,表示子类不能覆盖(即重定义)成员。 |
@see |
用于生成对可能与 当前项目。 |
@throws |
用于记录可能由函数或属性引发的异常类型。 |
@typeParam |
用于记录通用参数。@typeParam 标记后面是参数名、连字符和说明。TSDoc解析器识别这种语法,并将它提取到DocParamBlock节点中。 |
@virtual |
这个修饰符的语义类似于C#或Java中的 virtual 关键字。对于成员函数或属性,显式指示子类可以重写(即重定义)成员。 |
1.2 标记用法详解
本节整理和翻译自 TSDoc 规范官网
1.2.1 @alpha
指定 API 项的发布阶段为“alpha”。它旨在用于 第三方开发者最终,但尚未发布。该工具可能会从 公开发布。
例如:
/** * Represents a book in the catalog. * @public */ export class Book { /** * The title of the book. * @alpha */ public get title(): string; /** * The author of the book. */ public get author(): string; };
在这个例子中,Book.author从包含它的类继承了它的@public名称,而Book.title被标记为“alpha”。
1.2.2 @beta
指定 API 项的发布阶段为“测试版”。它已通过实验性发布给第三方开发人员 为了收集反馈。
例如:
/** * Represents a book in the catalog. * @public */ export class Book { /** * The title of the book. * @beta */ public get title(): string; /** * The author of the book. */ public get author(): string; };
在这个例子中,Book.author从包含它的类继承了它的@public名称,而Book.title被标记为“beta”。
1.2.3 @decorator
ECMAScript装饰器 有时是API契约的重要组成部分。然而,今天TypeScript编译器并不表示API消费者使用的. d.ts输出文件中的装饰器。@decorator标签提供了一种变通方法,允许在doc注释中引用decorator表达式。
例如:
class Book { /** * The title of the book. * @decorator `@jsonSerialized` * @decorator `@jsonFormat(JsonFormats.Url)` */ @jsonSerialized @jsonFormat(JsonFormats.Url) public website: string; }
1.2.4 @deprecated
此块标记表示不再支持 API 项,并且可能会在将来的版本中删除。 标记后跟一个描述推荐替代方案的句子。它递归应用 容器的成员。例如,如果一个类被弃用,那么它的所有成员也是如此。
例如:
/** * The base class for controls that can be rendered. * * @deprecated Use the new {@link Control} base class instead. */ export class VisualControl { . . . }
1.2.5 @defaultValue
如果未显式分配值,则此块标记用于记录字段或属性的默认值。此标记只能与属于 TypeScript class 或 interface 成员的字段或属性一起使用。
例如:
enum WarningStyle { DialogBox, StatusMessage, LogOnly } interface IWarningOptions { /** * Determines how the warning will be displayed. * * @remarks * See {@link WarningStyle| the WarningStyle enum} for more details. * * @defaultValue `WarningStyle.DialogBox` */ warningStyle: WarningStyle; /** * Whether the warning can interrupt a user's current activity. * @defaultValue * The default is `true` unless * `WarningStyle.StatusMessage` was requested. */ cancellable?: boolean; /** * The warning message */ message: string; }
1.2.6 @eventProperty
当应用于类或接口属性时,这表示该属性 返回事件处理程序可以附加到的事件对象。事件处理 API 是实现定义的,但通常属性返回类型是一个类 与成员如 addHandler()
和 removeHandler()
。文档工具可以 在“Events”标题下显示此类属性,而不是通常的“Properties”标题。
例如:
class MyClass { /** * This event is fired whenever the application navigates to a new page. * @eventProperty */ public readonly navigatedEvent: FrameworkEvent<NavigatedEventArgs>; }
1.2.7 @example
指示应作为示例演示如何使用 API 的文档部分。 它可能包括代码示例。
例如:
/** * Adds two numbers together. * @example * Here's a simple example: * ``` * // Prints "2": * console.log(add(1,1)); * ``` * @example * Here's an example with negative numbers: * ``` * // Prints "0": * console.log(add(1,-1)); * ``` */ export function add(x: number, y: number): number { }
例如:
/** * Parses a JSON file. * * @param path - Full path to the file. * @returns An object containing the JSON data. * * @example Parsing a basic JSON file * * # Contents of `file.json` * ```json * { * "exampleItem": "text" * } * ``` * * # Usage * ```ts * const result = parseFile("file.json"); * ``` * * # Result * ```ts * { * exampleItem: 'text', * } * ``` */
1.2.8 @experimental
例如:
/** * Represents a book in the catalog. * @public */ export class Book { /** * The title of the book. * @experimental */ public get title(): string; /** * The author of the book. */ public get author(): string; };
在这个例子中,Book.author从包含它的类继承了它的@public
名称,而Book.title被标记为“experimental”。
1.2.9 @inheritDoc
这个内联标签用于通过从另一个API项复制来自动生成一个API项的文档。inline tag参数包含对另一个项目的引用,它可能是一个不相关的类,甚至是从一个单独的NPM包导入的。
注意:声明引用的符号尚未最终确定。
什么被复制
@inheritDoc
标记不会复制整个注释体。仅复制以下组件:
- 摘要部分
@remarks
块@params
块@typeParam
块@returns
块
其他标签(如 @defaultValue
或 @example
)不会被复制,需要显式包含在 @inheritDoc
标签之后。当指定了@inheritDoc
标记时,不能在注释中指定summary部分和 @remarks
部分。
例如:
import { Serializer } from 'example-library'; /** * An interface describing a widget. * @public */ export interface IWidget { /** * Draws the widget on the display surface. * @param x - the X position of the widget * @param y - the Y position of the widget */ public draw(x: number, y: number): void; } /** @public */ export class Button implements IWidget { /** {@inheritDoc IWidget.draw} */ public draw(x: number, y: number): void { . . . } /** * {@inheritDoc example-library#Serializer.writeFile} * @deprecated Use {@link example-library#Serializer.writeFile} instead. */ public save(): void { . . . } }
1.2.10 @internal
指定不计划由第三方开发人员使用 API 项。该工具可能会修剪 公开发布的声明。在某些实现中,可能允许某些指定的包 使用内部 API 项,例如,因为包是同一产品的组件。
例如:
/** * Represents a book in the catalog. * @public */ export class Book { /** * The title of the book. * @internal */ public get _title(): string; /** * The author of the book. */ public get author(): string; };
1.2.11 @label
内联 {@label} 标记用于标记声明,以便可以使用 TSDoc 声明引用表示法。
{@label}符号尚未最终确定。
例如:
export interface Interface { /** * Shortest name: {@link InterfaceL1.(:STRING_INDEXER)} * Full name: {@link (InterfaceL1:interface).(:STRING_INDEXER)} * * {@label STRING_INDEXER} */ [key: string]: number; /** * Shortest name: {@link InterfaceL1.(:NUMBER_INDEXER)} * Full name: {@link (InterfaceL1:interface).(:NUMBER_INDEXER)} * * {@label NUMBER_INDEXER} */ [key: number]: number; /** * Shortest name: {@link InterfaceL1.(:FUNCTOR)} * Full name: {@link (InterfaceL1:interface).(:FUNCTOR)} * * {@label FUNCTOR} */ (source: string, subString: string): boolean; /** * Shortest name: {@link InterfaceL1.(:CONSTRUCTOR)} * Full name: {@link (InterfaceL1:interface).(:CONSTRUCTOR)} * * {@label CONSTRUCTOR} */ new (hour: number, minute: number); }
1.2.12 @link
{@link}
内联标记用于创建指向文档系统中其他页面或通用internet URLs的超链接。特别是,它支持引用API项的表达式。声明引用的符号尚未最终确定。
例如:
/** * Let's learn about the `{@link}` tag. * * @remarks * * Links can point to a URL: {@link https://github.com/microsoft/tsdoc} * * Links can point to an API item: {@link Button} * * You can optionally include custom link text: {@link Button | the Button class} * * Suppose the `Button` class is part of an external package. In that case, we * can include the package name when referring to it: * * {@link my-control-library#Button | the Button class} * * The package name can include an NPM scope and import path: * * {@link @microsoft/my-control-library/lib/Button#Button | the Button class} * * The TSDoc standard calls this notation a "declaration reference". The notation supports * references to many different kinds of TypeScript declarations. This notation was originally * designed for use in `{@link}` and `{@inheritDoc}` tags, but you can also use it in your * own custom tags. * * For example, the `Button` can be part of a TypeScript namespace: * * {@link my-control-library#controls.Button | the Button class} * * We can refer to a member of the class: * * {@link controls.Button.render | the render() method} * * If a static and instance member have the same name, we can use a selector to distinguish them: * * {@link controls.Button.(render:instance) | the render() method} * * {@link controls.Button.(render:static) | the render() static member} * * This is also how we refer to the class's constructor: * * {@link controls.(Button:constructor) | the class constructor} * * Sometimes a name has special characters that are not a legal TypeScript identifier: * * {@link restProtocol.IServerResponse."first-name" | the first name property} * * Here is a fairly elaborate example where the function name is an ECMAScript 6 symbol, * and it's an overloaded function that uses a label selector (defined using the `{@label}` * TSDoc tag): * * {@link my-control-library#Button.([UISymbols.toNumberPrimitive]:OVERLOAD_1) * | the toNumberPrimitive() static member} * * See the TSDoc spec for more details about the "declaration reference" notation. */
1.2.13 @override
这个修饰符的语义类似于C#或Java中的override关键字。对于成员函数或属性,显式指示此定义重写(即重新定义)从基类继承的定义。基类定义通常会被标记为虚拟的。
文档工具可以强制一致地应用
@virtual
、@override
和/或@sealed
修饰符,但是这不是TSDoc标准所要求的。
例如:
class Base { /** @virtual */ public render(): void { } /** @sealed */ public initialize(): void { } } class Child extends Base { /** @override */ public render(): void; }
1.2.14 @packageDocumentation
用于表示描述整个NPM包的文档注释(相对于属于该包的单个API项)。
@packageDocumentation
注释位于*.d.ts
文件中,该文件充当包的入口点,它应该是在该文件中遇到的第一个/**
注释。包含@packageDocumentation
标签的注释不应该用于描述单个API项。
例如:
// Copyright (c) Example Company. All rights reserved. Licensed under the MIT license. /** * A library for building widgets. * * @remarks * The `widget-lib` defines the {@link IWidget} interface and {@link Widget} class, * which are used to build widgets. * * @packageDocumentation */ /** * Interface implemented by all widgets. * @public */ export interface IWidget { /** * Draws the widget on the screen. */ render(): void; }
1.2.15 @param
用于记录函数参数。
@param
标记后面是参数名,后面是连字符,再后面是描述。
例如:
/** * Returns the average of two numbers. * * @remarks * This method is part of the {@link core-library#Statistics | Statistics subsystem}. * * @param x - The first input number * @param y - The second input number * @returns The arithmetic mean of `x` and `y` * * @beta */ function getAverage(x: number, y: number): number { return (x + y) / 2.0; }
1.2.16 @privateRemarks
启动不面向公众的其他文档内容的一部分。 工具必须从 API 参考网站(生成的
*.d.ts
文件)中省略整个部分, 以及包含内容的任何其他输出。
例如:
/** * The summary section should be brief. On a documentation web site, * it will be shown on a page that lists summaries for many different * API items. On a detail page for a single item, the summary will be * shown followed by the remarks section (if any). * * @remarks * * The main documentation for an API item is separated into a brief * "summary" section optionally followed by an `@remarks` block containing * additional details. * * @privateRemarks * * The `@privateRemarks` tag starts a block of additional commentary that is not meant * for an external audience. A documentation tool must omit this content from an * API reference web site. It should also be omitted when generating a normalized * *.d.ts file. */
1.2.17 @public
指定 API 项的发布阶段为“public”。已经正式发布给第三方开发者, 并且其签名保证稳定(例如,遵循语义版本控制规则)。
例如:
/** * Represents a book in the catalog. * @public */ export class Book { /** * The title of the book. * @internal */ public get _title(): string; /** * The author of the book. */ public get author(): string; };
1.2.18 @readonly
此修饰符标记指示 API 项应记录为只读,即使 TypeScript 类型系统可能另有指示。例如,假设一个类属性有一个 setter 函数,该函数始终 引发异常,说明无法分配属性;在这种情况下,
@readonly
修饰符 可以添加,以便属性在文档中显示为只读。
例如:
export class Book { /** * Technically property has a setter, but for documentation purposes it should * be presented as readonly. * @readonly */ public get title(): string { return this._title; } public set title(value: string) { throw new Error('This property is read-only!'); } }
1.2.19 @remarks
API项目的主要文件被分成一个简短的“总结”部分,随后是一个更详细的“备注”部分。在文档网站上,索引页(例如显示类的成员)将只显示简短的摘要,而详细页(例如描述单个成员)将显示摘要,后跟备注。
@remarks
块标记结束摘要部分,并开始文档注释的备注部分。
例如:
/** * The summary section should be brief. On a documentation web site, * it will be shown on a page that lists summaries for many different * API items. On a detail page for a single item, the summary will be * shown followed by the remarks section (if any). * * @remarks * * The main documentation for an API item is separated into a brief * "summary" section optionally followed by an `@remarks` block containing * additional details. * * @privateRemarks * * The `@privateRemarks` tag starts a block of additional commentary that is not meant * for an external audience. A documentation tool must omit this content from an * API reference web site. It should also be omitted when generating a normalized * *.d.ts file. */
1.2.20 @returns
用于记录函数的返回值。
例如:
/** * Returns the average of two numbers. * * @remarks * This method is part of the {@link core-library#Statistics | Statistics subsystem}. * * @param x - The first input number * @param y - The second input number * @returns The arithmetic mean of `x` and `y` * * @beta */ function getAverage(x: number, y: number): number { return (x + y) / 2.0; }
1.2.21 @sealed
这个修饰符的语义类似于C#或Java中的sealed关键字。对于类,指示子类不能从类继承。对于成员函数或属性,表示子类不能覆盖(即重定义)成员。
文档工具可以强制一致地应用
@virtual
、@override
/或@sealed
修饰符,但是这不是TSDoc标准所要求的。
例如:
在下面的代码示例中,Child.render()重写虚拟成员Base.render(),但是Base.initialize()不能被重写,因为它被标记为“sealed”。
class Base { /** @virtual */ public render(): void { } /** @sealed */ public initialize(): void { } } class Child extends Base { /** @override */ public render(): void; }
1.2.22 @see
用于构建API项或可能与当前项相关的其他资源的引用列表。
注意:JSDoc试图自动超链接@see后面的文本。因为这对于纯文本是不明确的,所以TSDoc需要一个显式的{@link}标记来创建超链接。
例如:
/** * Parses a string containing a Uniform Resource Locator (URL). * @see {@link ParsedUrl} for the returned data structure * @see {@link https://tools.ietf.org/html/rfc1738|RFC 1738} * for syntax * @see your developer SDK for code samples * @param url - the string to be parsed * @returns the parsed result */ function parseURL(url: string): ParsedUrl;
@see是块标签。每个块都成为参照列表中的一个项目。例如,文档系统可能会将上述块呈现如下:
`function parseURL(url: string): ParsedUrl;` Parses a string containing a Uniform Resource Locator (URL). ## See Also - ParsedUrl for the returned data structure - RFC 1738 for syntax - your developer SDK for code samples
1.1.23 @throws
用于记录可能由函数或属性引发的异常类型。
应该使用单独的
@throws
块来记录每个异常类型。此标记仅供参考,并不限制引发其他类型。建议但不要求@throws
块以只包含异常名的行开始。
例如:
/** * Retrieves metadata about a book from the catalog. * * @param isbnCode - the ISBN number for the book * @returns the retrieved book object * * @throws {@link IsbnSyntaxError} * This exception is thrown if the input is not a valid ISBN number. * * @throws {@link book-lib#BookNotFoundError} * Thrown if the ISBN number is valid, but no such book exists in the catalog. * * @public */ function fetchBookByIsbn(isbnCode: string): Book;
1.2.24 @typeParam
用于记录通用参数。``@typeParam` 标记后面是参数名,后面是连字符,再后面是描述。TSDoc解析器识别这种语法,并将它提取到DocParamBlock节点中。
例如:
** * Alias for array * * @typeParam T - Type of objects the list contains */ type List<T> = Array<T>; /** * Wrapper for an HTTP Response * @typeParam B - Response body * @param <H> - Headers */ interface HttpResponse<B, H> { body: B; headers: H; statusCode: number; }
1.2.25 @virtual
这个修饰符的语义类似于C#或Java中的 virtual 关键字。对于成员函数或属性,显式指示子类可以重写(即重定义)成员。
文档工具可以强制一致地应用
@virtual
、@override
和/或@sealed
修饰符,但是这不是TSDoc标准所要求的。
例如:
class Base { /** @virtual */ public render(): void { } /** @sealed */ public initialize(): void { } } class Child extends Base { /** @override */ public render(): void; }
1.3 TSDoc 语法解析器的参考实现 @microsoft/TSDOC
2. JSDoc 模块:用于生成 JavaScript 接口文档
JavaScript 的 API 文档生成器。
2.1 JSDoc 的安装
npm install -g jsdoc
2.2 JSDoc 的用法
如果全局安装了 JSDoc,可以运行 jsdoc
命令来生成指定 .js
文件的文档。
例如:
jsdoc myfile.js
3. WebAPI 的 markdown 文档生成工具 apidoc-markdown
3.1 安装
pnpm install --global apidoc-markdown # For programmatic usage or local project CLI install pnpm install apidoc-markdown
3.2 命令行工具用法
为您的API生成一个简单且可移植的Markdown文档。
其语法格式如下:
apidoc-markdown -i <path> -o <output_file> [-t <template_name>] [--multi] [--createPath] [--prepend <file_path>]
其中:
Options: --version Show version number [boolean] -i, --input Input source files path [string] [required] [default: "src"] -o, --output Output file or directory to write output to. [string] [required] -t, --template Name of the template to be used (`default`, `bitbucket`) or path to an EJS template file. [string] [default: "default"] --header Path to file content to add at the top of the documentation. [string] --footer Path to file content to add at the bottom of the documentation. [string] --prepend Path to file content to add before route groups documentation. [string] --multi Output one file per group to the `output` directory. [boolean] [default: false] --createPath Recursively create directory arborescence to the `output` directory. [boolean] [default: false] -h, --help Show help [boolean]
例如:
apidoc-markdown -i src -o doc.md Generate from `src` source files to `doc.md` apidoc-markdown --input src --output doc.md Generate from `src` source files to `doc.md` apidoc-markdown -i src -o doc.md -t bitbucket Generate from `src` source files to `doc.md` using the `bitbucket` template apidoc-markdown -i src -o doc.md -t my_custom_template.md Generate from `src` source files to `doc.md` using a provided template file apidoc-markdown -i src -o doc --multi Generate from `src` source files to `doc/<group>.md` apidoc-markdown - https://github.com/rigwild/apidoc-markdown
3.3 编程API用法
暂未编辑