如何使用闭包编译器在 javascript 中注释扩展泛型类型的 class

How to annotate in javascript a class that extends a generic type, using closure compiler

我在 javascript 中创建了一个 Class 工厂,它接受类型 T 并生成一个新的增强型 class 类型 T,简单。

我正在使用 google 的闭包编译器来编译 javascript,并使用闭包的注释来注释类型等。挑战是如何注释扩展类型 T 的 Class ,其中 T 是通用类型。

这是一个简化的 Class Enhanced 扩展了另一种类型:

/**
 * @constructor
 */
function Foo(){
    this.x = 'x';
};

/**
 * @constructor
 */
function Bar(){
    this.y = 'y';
};

/**
 * @constructor
 * @param {function(new:T)} FooOrBar
 * @extends {T}
 * @template T
 */
function Enhanced(FooOrBar){
    FooOrBar.call(this);
    this.z = 'z';
};

/** @type Enhanced.<Foo> */
var enhancedFoo = new Enhanced(Foo);

/** @type Enhanced.<Bar> */
var enhancedBar = new Enhanced(Bar);

当我用闭包编译器编译这段代码时,我收到编译器警告:

'Could not resolve type in @extends tag of Enhanced'.

因此,显然编译器不知道在编译此 class 时从何处推断 T。

有人可以指出为什么编译器在创建 class 时无法推断类型,或者是否有办法将生成的 class 注释为扩展类型 T。

my use case is Class factories where the classes cannot be annotated because they're created at runtime

听起来 Closure 编译器可能无法为您提供帮助,至少不能使用这种特殊方法。

您打算 Enhanced 成为一个接受 class 和 returns 和 class 的函数。肯定有一些语言以这种方式在 classes 上运行(Python、Javascript、Ruby 等)。

但是闭包编译器需要静态 classes 才能进行静态分析。这不一定是它必须工作的方式,但这是它设计的工作方式。

一个粗略的经验法则是:如果你可以在 Java 中表示类型,你就可以在 Closure 注释中表示类型。

当然,这不是 GWT;你不是在写 Java。您可以使用您的 JS-fu 编写您想要的所有元 classes。但是不要期望 Closure Compiler 一定能够对其进行类型检查。


好消息是,遵循这种静态 classes 范式的语言背后确实有数十年的研究和最佳实践:C++、Java、C#。如果你熟悉这些,你可能会问自己"How would I do this in those languages?"

您的实际问题(无论是什么)可能已被这些 OO 语言的设计模式解决了数百或数千次,您也可以这样做。