如何使用 Google Closure Compiler 注释可选参数?

How to annotate an optional parameter using Google Closure Compiler?

我对 Google Closure Compiler (GCC) 还很陌生。我对如何使其将参数显示为可选参数感到困惑...

这是我的部分代码:

/**
 * @param {string} name The event name
 * @param {Date} date1 The start date (If alone, the single date) of the event
 * @param {Date} date2 The end date of the event
 */
function getEventLink (name,date1,date2) {
    // code here
}

我想让 date1 成为可选的...我发现一个有用的 page on the Closure Compiler,但我没有看到可选的选项...这可能吗?如果可以,我该怎么做?

我试过:

/**
 * @param {string} name The event name
 * @param {Date} date1 The start date (If alone, the single date) of the event
 * @param {Date|undefined} date2 The end date of the event
 */
function getEventLink (name,date1,date2) {
    // code here
}

此外,使用 null 而不是 undefined,但两者似乎都不起作用...

Google Closure Compiler 依靠注解来完成它的工作。因为 JavaScript 没有类型的语法,所以必须在源文件中将它们写为注释。

这些评论是使用 JSDoc 编写的,尽管 GCC 多年来一直带有自己的标签(例如 @polymer 不是“本机”JSDoc 标签),但它确实支持 JSDoc 类型表达式。 (而且 JSDoc 在其类型表达式中也支持 Google 闭包类型系统。)

注释?表达?什么?!

一个简单的例子将说明:

/**
 * @param {string|number} x
 */
const a = x => x;

这是注释:@param {string|number} x。是一个东西的信息:

  1. 是一个参数
  2. 它的名字是x
  3. 它的类型是字符串或数字

这是类型表达式:{string|number}。它是关于事物类型的信息。

JavaScript中的可选参数

如您所知,JavaScript 允许在函数签名中为参数指定默认值:

const a = (x=1, y=2, z=3) => x + y + z;

当且仅当 undefined 隐式或显式传递时才使用这些默认值:

a();
//=> 6

a(undefined, undefined, 20);
//=> 23

a(null, null, 20);
//=> 20 (null doesn't trigger the default value and is coerced to 0)

JSDoc 中的可选参数

可选参数有两个可能的注释。随便选一个你喜欢的:

/** @param {number=} x */

/** @param {number} [x] */

然而只有一个可选参数默认值:

/** @param {number} [x=1] */

GCC 的可选参数

尽管 a(undefined, undefined, 20) 在 JavaScript 中在技术上是可行的,但它是一种糟糕的开发人员体验,GCC 可能 抱怨。

函数签名中没有声明默认值的可选参数应该放在最后,否则 GCC 将发出警告。

在此示例中,z 是唯一的非可选参数,但它是最后一个参数:

/**
 * @param {number} [x=1]
 * @param {number} [y=2]
 * @param {number} z
 */
const a = (x, y, z) => (x ?? 1) + (y ?? 2) + z;

a(undefined, undefined, 20);
//=> 23

GCC 输出:

JSC_OPTIONAL_ARG_AT_END: optional arguments must be at the end at line 11 character 10
const a = (x, y, z) => (x ?? 1) + (y ?? 2) + z;
          ^

如果所有参数都是可选的,这当然不是问题。这些例子都OK:

/**
 * @param {number} [x=1]
 * @param {number} [y=2]
 * @param {number} [z=3]
 */
const a = (x, y, z=3) => (x ?? 1) + (y ?? 2) + z;

/**
 * @param {number} [x=1]
 * @param {number} [y=2]
 * @param {number} [z=3]
 */
const a = (x, y, z) => (x ?? 1) + (y ?? 2) + (z ?? 3);

/**
 * @param {number} [x=1]
 * @param {number} [y=2]
 * @param {number} [z=3]
 */
const a = (x=1, y=2, z=3) => x + y + z;

进一步阅读