注释由构造函数参数设置的实例属性?

Annotating instance properties which are set by constructor parameters?

使用google闭包编译器时,是否需要注解构造函数参数设置的属性?例如

/**
 * @constructor
 * @param {string} bar
 * @param {number} barPrivate
 */
var Foo = function(bar, barPrivate) {
  this.bar = bar;
  this.barPrivate_ = barPrivate;
};

如果我写这个,编译器是否足够聪明来弄清楚:

  1. bar 属性 的类型是 {string}?
  2. barPrivate 属性 的类型是 {number}?
  3. barPrivate 属性 是 @private?

还是我需要更明确?

/**
 * @constructor
 * @param {string} bar
 * @param {number} barPrivate
 */
var Foo = function(bar, barPrivate) {
  /** @type {string} */
  this.bar = bar;
  /** @private {number} */
  this.barPrivate_ = barPrivate;
};

后一种形式似乎较少"DRY",但这是我们一直在使用的保险起见。无论哪种方式,我都没有找到任何文档...

在做了一些最小的探索之后 AST with visibility declarations (but no type declarations)AST when type declarations are included...对我来说这意味着可见性声明可能是必要的但类型声明不是?

我必须 运行 一些测试才能确定,但​​这是我的理解:

  1. 和 2. 是的,编译器知道 bar 是类型 stringbarPrivate 是类型 number但仅在构造函数调用期间有效。它不会强制要求 this.bar 在后面的代码中只能是一个字符串。

  2. 不,编译器只会在您提供显式示例中的注释时强制执行 @private 访问。

其中一些类型的检查在 new type inference (NTI) 中更可靠,但可能不是这些特定情况。

当您在另一个方法中(或稍后在构造函数中)将不同的类型分配给 属性 时,尝试查看编译器在有或没有这些注释的情况下做了什么。

是否在方法中为局部变量指定类型也会出现同样的问题。

edit:正如 Chad Killingsworth 指出的那样,在这个简单的示例中,编译器可以推断出 this.bar 是一个没有附加注释的字符串;但是如果在其他地方将其他类型分配给 this.bar 然后 "all bets are off",我不知道编译器会做什么。