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

4

我对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
}

我希望date2是可选的...我在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,但似乎都不起作用...

1
一般来说,我相信JavaScript不允许您创建除最后一个或从后面开始的组以外的参数是可选的,除非在函数调用中您明确地使用nullundefined等。 - Samathingamajig
我知道JavaScript不能这样做,但是你知道使用GCC是否可以使参数成为“可选的”吗? - Jacob Hornbeck
1个回答

4

Google Closure Compiler 依赖注释来完成其工作。由于 JavaScript 没有类型的语法,这些类型必须作为注释写在源代码中。
这些注释使用 JSDoc 编写,尽管 GCC 多年来已经带有自己的标签(例如,`@polymer` 不是“本地”的 JSDoc 标签),但它确实支持 JSDoc 类型表达式。(而且 JSDoc 在其类型表达式中也支持 Google Closure Type System。)
注释?表达式?什么?!
一个简单的例子将澄清:
/**
 * @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] */

然而,对于一个可选参数with默认值,只有一个:
/** @param {number} [x=1] */

GCC中的可选参数

虽然在JavaScript中a(undefined, undefined, 20)是技术上可能的,但这是一个糟糕的开发者体验,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;
          ^

当所有参数都是可选的时候,这当然不是一个问题。以下示例均正确:
/**
 * @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;

更多阅读


非常有帮助,谢谢。我对这种方式使用多个带描述的参数有点迷惑;它只为我显示第一个参数的描述。这是正常的吗,只是 JSDoc / GCC 的限制吗?谢谢。 - nikodaemus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接