Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I created a Class factory in javascript that takes type T and generates a new enhanced class of type T, simple.

I'm using google's closure compiler to compile javascript, and closure's annotation to annotate Types etc. The challenge is how to annotate a Class that extends type T, where T is a generic type.

Here is a simplified Class Enhanced that extends another type:

/**
 * @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);

when I compile this code with the closure compiler I get a compiler warning:

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

So, obviously the compiler does not know from where to infer T when this class is compiled.

Can someone please point out why the compiler can't infer the type when the class is created, or if there is a way to annotate a generated class as extending type T.

like image 616
Joel Kornbluh Avatar asked Dec 11 '25 11:12

Joel Kornbluh


1 Answers

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

It sounds like the Closure Compiler may not be able to help you out here, at least not with this particular approach.

You intend Enhanced to be a function that takes a class and returns a class. There are certainly languages in which operate on classes in this way (Python, Javascript, Ruby, etc.).

But the Closure Compiler requires static classes in order to do its static analysis. That isn't necessarily the way that it has to work, but that is the way it was designed to work.

A rough rule of thumb is this: if you can represent the types in Java, you can represent the types in Closure annotations.

Of course, this isn't GWT; you're not writing Java. You can use your JS-fu to write all the meta classes you want. But don't expect the Closure Compiler to necessarily be able to type check it.


The good news is that there is literally decades of research and best practices behind languages following this paradigm of static classes: C++, Java, C#. If you are familiar with these, you might ask yourself "How would I do this in those languages?"

Your actual problem (whatever it is) has likely been solved hundreds or thousands of times by a design pattern for these OO languages, and you could do the same.

like image 78
Paul Draper Avatar answered Dec 14 '25 00:12

Paul Draper