TypeScript 的注释指令

227 阅读2分钟

所谓“注释指令”,指的是采用 JS 双斜杠注释的形式,向编译器发出的命令。

// @ts-nocheck

// @ts-nocheck告诉编译器不对当前脚本进行类型检查,可以用于 TypeScript 脚本,也可以用于 JavaScript 脚本。

// @ts-check

如果一个 JavaScript 脚本顶部添加了// @ts-check,那么编译器将对该脚本进行类型检查,不论是否启用了checkJs编译选项。

// @ts-ignore

// @ts-ignore告诉编译器不对下一行代码进行类型检查,可以用于 TypeScript 脚本,也可以用于 JavaScript 脚本。

// @ts-expect-error

// @ts-expect-error主要用在测试用例,当下一行有类型错误时,它会压制 TypeScript 的报错信息(即不显示报错信息),把错误留给代码自己处理。

function doStuff(abc: string, xyz: string) {
  assert(typeof abc === "string");
  assert(typeof xyz === "string");
  // do some stuff
}

// @ts-expect-error
expect(() => {
  doStuff(123, 456);
}).toThrow();

JSDoc

TypeScript 直接处理 JS 文件时,如果无法推断出类型,会使用 JS 脚本里面的 JSDoc 注释。

使用 JSDoc 时,有两个基本要求。

(1)JSDoc 注释必须以/**开始 (2)JSDoc 注释必须与它描述的代码处于相邻的位置,并且注释在上,代码在下。

@typedef

@typedef命令创建自定义类型,等同于 TypeScript 里面的类型别名。

/**
 * @typedef {(number | string)} NumberLike
 */

上面示例中,定义了一个名为NumberLike的新类型,它是由numberstring构成的联合类型,等同于 TypeScript 的如下语句。

type NumberLike = string | number;

@type

@type命令定义变量的类型。

/**
 * @type {string}
 */
let a;

上面示例中,@type定义了变量a的类型为string

@type命令中可以使用由@typedef命令创建的类型。

/**
 * @typedef {(number | string)} NumberLike
 */

/**
 * @type {NumberLike}
 */
let a = 0;

@type命令中允许使用 TypeScript 类型及其语法。

/**@type {true | false} */
let a;

/** @type {number[]} */
let b;

/** @type {Array<number>} */
let c;

/** @type {{ readonly x: number, y?: string }} */
let d;

/** @type {(s: string, b: boolean) => number} */
let e;

@param

@param命令用于定义函数参数的类型。

/**
 * @param {string}  x
 */
function foo(x) {}

如果是可选参数,需要将参数名放在方括号[]里面。

/**
 * @param {string}  [x]
 */
function foo(x) {}

方括号里面,还可以指定参数默认值。

/**
 * @param {string} [x="bar"]
 */
function foo(x) {}

上面示例中,参数x的默认值是字符串bar

@return,@returns

@return@returns命令的作用相同,指定函数返回值的类型。

/**
 * @return {boolean}
 */
function foo() {
  return true;
}

/**
 * @returns {number}
 */
function bar() {
  return 0;
}

@extends 和类型修饰符

@extends命令用于定义继承的基类。

/**
 * @extends {Base}
 */
class Derived extends Base {
}

@public@protected@private分别指定类的公开成员、保护成员和私有成员。

@readonly指定只读成员。

class Base {
  /**
   * @public
   * @readonly
   */
  x = 0;

  /**
   *  @protected
   */
  y = 0;
}