Document generic type parameters in JSDOC
Asked Answered
I

3

63

In JSDoc there exists the possibility to document the exact types of array contents like this:

/** @param {Array.<MyClass>} myClasses An array of MyClass objects. */
TestClass.protoype.someMethod = function( myClasses ){
   myClasses[0].aMethodOnMyClass();
}

This makes code completion in IDEs like WebStorm actually provide the right type information after the [0].. This works well for the Array type, however I have my own collection types where I would like to make use of this feature, too. The problem is I cannot find the right syntax (maybe because there is none, yet). I would love to be able to declare my class somehow like this:

/**
 * @typeparam {T} the type parameter
 * @constructor {Test2.<T>}
 * */
Test2 = function(){};

/**
 * @returns {T} a value of type T, where T is the generic type parameter of Test2
 */
Test2.prototype.getGenericValue = function(){}

This syntax or feature does not work with my IDE and is not listed here, so I am wondering whether there is a syntax for this use-case, either for WebStorm or any other JS authoring tool.

Impede answered 15/4, 2013 at 14:23 Comment(0)
I
55

In the meantime, support for this feature has been finalized and is now documented on the Closure Compiler JSDOC page for generics.

Basically it works like this for ES6 classes:

/** @template T */
class Foo {
  /** @return {T} */
  get() { ... };

  /** @param {T} t */
  set(t) { ... };
}

... and like this for pre-ES6 code:

/**
 * @constructor
 * @template T
 */
Foo = function() { ... };

and

/** @return {T} */
Foo.prototype.get = function() { ... };

/** @param {T} t */
Foo.prototype.set = function(t) { ... };

WebStorm 7.0 did not support this feature at the time the original answer was written, but as of today (2019) all JetBrains IDEs understand this syntax, properly.

Impede answered 11/10, 2013 at 16:18 Comment(1)
Can you show an example of this being implemented?Glennisglennon
U
43

You can try using @template tag (undocumented tag used in Google Closure library - extremely limited form of generics). Something like:

/**   
 * Search an array for the first element that satisfies a given condition and   
 * return that element.   
 * @param {Array.<T>|goog.array.ArrayLike} arr Array or array   
 *     like object over which to iterate.   
 * @param {?function(this:S, T, number, ?) : boolean} f The function to call   
 *     for every element. This function takes 3 arguments (the element, the   
 *     index and the array) and should return a boolean.   
 * @param {S=} opt_obj An optional "this" context for the function.   
 * @return {T} The first array element that passes the test, or null if no   
 *     element is found.   
 * @template T,S   
 */  
goog.array.find = function(arr, f, opt_obj) {    
   var i = goog.array.findIndex(arr, f, opt_obj);    
   return i < 0 ? null : goog.isString(arr) ? arr.charAt(i) : arr[i];  
}; 

WebStorm uses this tag for type hinting - i.e. if we pass array of strings to goog.array.find in the sample above , IDE will know that return type is string, so string completion options will be suggested etc.

Not sure if this is what you are looking for... The post that looks related is here.

Ulund answered 15/4, 2013 at 15:29 Comment(1)
Thanks, I just found this out myself from this YouTrack issue and this Closure Compiler Changeset. Is there support for this on the class level? My tests indicate that this works for "function local type parameters" only.Impede
O
3

The following code works fine for me in WebStorm 8.

/** @type {Array.<MyPair.<Event, Array.<Thought>>>} */
scope.pairs = [];

/**
 * @template TFirst, TSecond
 */
function MyPair(first, second){
    this.first = first;
    this.second = second;
}
/** @type {TFirst} */
MyPair.prototype.first = null;
/** @type {TSecond} */
MyPair.prototype.second = null;

...
function Event(){}
...
...
function Thought(){}
...
Owe answered 16/9, 2014 at 8:50 Comment(2)
In above example, it worked with Event and Thought object as well.Owe
Yes, in the meantime a lot of this has been implemented in WS8, but still there are open issues that will only be fixed in WS9 - see my answer and the linked issues.Impede

© 2022 - 2024 — McMap. All rights reserved.