Skip to Content
TypeScript注释和文档

注释和文档

JSDoc 与注释

有两种类型的注释,JSDoc(/** ... */)和非 JSDoc 的普通注释(// .../* ... */)。

  • 使用 /** JSDoc */ 注释编写文档,即代码用户应该阅读的注释。
  • 使用 // line comments 编写实现注释,即只与代码实现本身相关的注释。

JSDoc 注释可以被工具(如编辑器和文档生成器)理解,而普通注释仅供其他人阅读。

多行注释

多行注释与周围代码保持相同的缩进级别。它们必须使用多个单行注释(// 风格),而不是块注释风格(/* */)。

// 这是 // 可以的
/* * 这应该 * 使用多个 * 单行注释 */ /* 这应该使用 // */

注释不应包裹在由星号或其他字符绘制的框中。

JSDoc 一般形式

JSDoc 注释的基本格式如以下示例所示:

/** * 多行 JSDoc 文本写在这里, * 正常换行。 * @param arg 一个用于执行某操作的数字。 */ function doSomething(arg: number) { … }

或者单行示例:

/** 这个简短的 jsdoc 描述了该函数。 */ function doSomething(arg: number) { … }

如果单行注释溢出为多行,它必须使用多行风格,/***/ 各占一行。

许多工具从 JSDoc 注释中提取元数据来执行代码验证和优化。因此,这些注释必须格式正确。

Markdown

JSDoc 使用 Markdown 编写,但在必要时可以包含 HTML。

这意味着解析 JSDoc 的工具会忽略纯文本格式,所以如果你这样写:

/** * Computes weight based on three factors: * items sent * items received * last timestamp */

它会被渲染成这样:

Computes weight based on three factors: items sent items received last timestamp

相反,应该写成 Markdown 列表:

/** * Computes weight based on three factors: * * - items sent * - items received * - last timestamp */

JSDoc 标签

Google 风格允许使用 JSDoc 标签的一个子集。大多数标签必须独占一行,标签位于行首。

/** * "param" 标签必须独占一行,不能合并。 * @param left 对左参数的描述。 * @param right 对右参数的描述。 */ function add(left: number, right: number) { ... }
/** * "param" 标签必须独占一行,不能合并。 * @param left @param right */ function add(left: number, right: number) { ... }

行换行

换行的块标签缩进四个空格。换行的描述文本可以与前几行的描述对齐,但不鼓励这种水平对齐。

/** * 演示长 param/return 描述的换行。 * @param foo 这是一个描述特别长的参数, * 一行放不下。 * @return 返回的内容描述也太长, * 一行放不下。 */ exports.method = function(foo) { return 5; };

换行 @desc@fileoverview 描述时不要缩进。

为模块的所有顶级导出编写文档

使用 /** JSDoc */ 注释向代码的用户传达信息。避免仅仅重述属性或参数名称。你还应该为所有目的不能从其名称中立即看出的属性和方法(导出/公开的或非导出/公开的)编写文档,由审查者判断。

**例外:**仅为了被工具消费而导出的符号(例如 @NgModule 类)不需要注释。

类注释

类的 JSDoc 注释应该为读者提供足够的信息,以了解如何以及何时使用该类,以及正确使用该类所需的任何额外注意事项。构造函数的文本描述可以省略。

方法和函数注释

如果方法、参数和返回值的描述从方法 JSDoc 的其余部分或方法名称和类型签名中显而易见,则可以省略。

方法描述以动词短语开头,描述方法的功能。这个短语不是祈使句,而是以第三人称书写,就好像前面有一个隐含的“此方法…”。

参数属性注释

参数属性(Parameter Property) 是以修饰符 privateprotectedpublicreadonly 为前缀的构造函数参数。参数属性同时声明了一个参数和一个实例属性,并隐式地将参数赋值给它。例如,constructor(private readonly foo: Foo) 声明构造函数接受一个参数 foo,同时也声明了一个私有只读属性 foo,并在执行构造函数的其余部分之前将参数赋值给该属性。

要为这些字段编写文档,请使用 JSDoc 的 @param 注解。编辑器会在构造函数调用和属性访问时显示描述。

/** 此类演示了如何为参数属性编写文档。 */ class ParamProps { /** * @param percolator 用于冲泡的过滤器。 * @param beans 要冲泡的咖啡豆。 */ constructor( private readonly percolator: Percolator, private readonly beans: CoffeeBean[]) {} }
/** 此类演示了如何为普通字段编写文档。 */ class OrdinaryClass { /** 将在下次调用 brew() 时使用的咖啡豆。 */ nextBean: CoffeeBean; constructor(initialBean: CoffeeBean) { this.nextBean = initialBean; } }

JSDoc 类型注解

在 TypeScript 源代码中,JSDoc 类型注解是冗余的。不要在 @param@return 块中声明类型,不要在使用 implementsenumprivateoverride 等关键字的代码上写 @implements@enum@private@override 等。

编写真正有信息量的注释

对于非导出符号,有时函数或参数的名称和类型就足够了。但代码通常会受益于比仅仅变量名更多的文档!

  • 避免仅仅重述参数名称和类型的注释,例如

    /** @param fooBarService Foo 应用的 Bar 服务。 */
  • 由于此规则,@param@return 行仅在添加信息时才需要,否则可以省略。

    /** * 发送请求以开始冲泡咖啡。 * @param amountLitres 要冲泡的量。必须适合壶的大小! */ brew(amountLitres: number, logger: Logger) { // ... }

调用函数时的注释

当方法名称和参数值不足以传达参数的含义时,应使用”参数名”注释。

在添加这些注释之前,考虑重构方法以接受一个接口并解构它,以大大提高调用处的可读性。

“参数名”注释放在参数值之前,包含参数名称和 = 后缀:

someFunction(obviousParam, /* shouldRender= */ true, /* name= */ 'hello');

现有代码可能使用旧式的参数名注释风格,将这些注释放在参数值之后并省略 =。在文件中为了保持一致性继续使用这种风格是可以接受的。

someFunction(obviousParam, true /* shouldRender */, 'hello' /* name */);

将文档放在装饰器之前

当类、方法或属性同时有装饰器(如 @Component)和 JSDoc 时,请确保将 JSDoc 写在装饰器之前。

  • 不要在装饰器和被装饰的语句之间写 JSDoc。

    @Component({ selector: 'foo', template: 'bar', }) /** 打印 "bar" 的组件。 */ export class FooComponent {}
  • 在装饰器之前写 JSDoc 块。

    /** 打印 "bar" 的组件。 */ @Component({ selector: 'foo', template: 'bar', }) export class FooComponent {}
Last updated on