有没有一种方法可以在Google Closure Compiler中使用枚举作为类型?

4

我尝试做类似于@param {window.MyNamespace.MyEnum} myVar的事情,但编译器抱怨有一个JSC_TYPE_PARSE_ERROR: Bad type annotation. Unknown type window.MyNamespace.MyEnum

我应该在枚举上使用@typedef,还是只使用@param {number},如果我的枚举是@enum {number}?我真的更喜欢枚举这个东西,因为其他值实际上是不允许的。

(function (MyNamespace) {
  /**
   * @enum {number}
   */
  MyNamespace.MyEnum = {
    FOO: 1,
    BAR: 2,
    BAZ: 3
  }
  /**
   * @constructor
   * @param {Object} foo
   */
  MyNamespace.MyClass = function (foo) {
    this.foo = foo
  }
  /**
   * @constructor
   * @param {MyNamespace.MyClass} bar
   */
  MyNamespace.MyOtherClass = function (bar) {
    this.bar = bar
  }
  /**
   * @param {MyNamespace.MyEnum} baz
   */
  MyNamespace.MyOtherClass.prototype.someMethod = function (baz) {
  }
})(window.MyNamespace = window.MyNamespace || {})

除非你定义了命名空间 window,否则 window 不应该成为类型声明的一部分。 - Felix Kling
我按照 jQuery 企业文章中的写法定义了命名空间:链接,但是闭包编译器无法找到类型,所以我将命名空间定义的参数部分移动到函数中。 - Aeveus
你贴出的代码还是会报错吗? - Felix Kling
简单的优化应该可以正常工作,因为它们不涉及注释类型的内容。它只是删除空格和注释,并重命名本地方法。我感兴趣的是高级优化。 - Aeveus
我仍然收到 JSC_TYPE_PARSE_ERROR: Bad type annotation. 你能把你用的完整代码发一下吗? - Aeveus
显示剩余6条评论
1个回答

4
使用函数参数来定义别名类型在Closure-compiler中的支持不够完善。使用--output_wrapper标志在编译后封装你的代码。以下代码可以正确编译:
/** @const */
var MyNamespace = window.MyNamespace || {};

/** @enum {number} */
MyNamespace.MyEnum = {
  FOO: 1,
  BAR: 2,
  BAZ: 3
};
/**
 * @constructor
 * @param {Object} foo
 */
MyNamespace.MyClass = function (foo) {
  this.foo = foo
};
/**
 * @constructor
 * @param {MyNamespace.MyClass} bar
 */
MyNamespace.MyOtherClass = function (bar) {
  this.bar = bar
};
/** @param {MyNamespace.MyEnum} baz */
MyNamespace.MyOtherClass.prototype.someMethod = function (baz) {};

好的,它可以正确编译,但参数类型检查将仅限于枚举类型,而不是不同的枚举值。如果您调用MyNameSpace.MyOtherClass.someMethod(4),即使4不是枚举中定义的值,它也不会给您警告...但也许我对此太严格了。 - Sebastien
@Sebastien 枚举类型不会被验证,也不应该以那种方式使用。它的用途是使用符号 MyNamespace.MyEnum.BAR,编译器将在编译期间将其替换为值。 - Chad Killingsworth
没错,但是即使你将参数类型指定为"MyNamespace.MyEnum",如果你使用一个数字调用这个方法,它也不会给你任何警告(但是好吧,我也没有找到解决办法...)。 - Sebastien
@Sebastien 这种行为是设计上的。我建议您提出另一个问题,说明您想要实现的细节。 - Chad Killingsworth
1
@Sebastien 编译器的默认警告级别不会报告类型不匹配的问题。 您需要使用--warning_level VERBOSE,它启用类型检查。 然后调用someMethod(4)将触发编译器警告:“实际参数1与形式参数不匹配。 找到:number。 需要:MyNamespace.MyEnum<number> - TachyonVortex

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