JSDoc: document generic type that works for grandchildren classes


JSDoc: document generic type that works for grandchildren classes



Documenting generic type works for direct inheritance. But when I have a inheritance chain, there is no way to make it work for the grandchildren class. Here is an example:


* @property {string} color
* @template {T}
*/
class MyColor {
constructor() {
this.color = 'unknown';
}

/**
* @returns {T}
*/
static makeColor() {
return /**@type {T}*/ new this.prototype.constructor();
}
}

/**
* @extends MyColor<Red>
* @template {T}
*/
class Red extends MyColor {
constructor() {
super();
this.color = 'red';
}
}

/**
* @extends Red<DarkRed>
*/
class DarkRed extends Red {
constructor() {
super();
this.level = 2;
}

darker() {
this.level += 1;
}
}

const circle = DarkRed.makeColor();



DarkRed.makeColor only recognizes the return as Red, but not DarkRed. Is there a way to make it work with @template? Or is there any other way to make it work?


DarkRed.makeColor


Red


DarkRed


@template



I am using WebStorm as the IDE.




1 Answer
1



From https://github.com/google/closure-compiler/wiki/Generic-Types#inheritance-of-generic-types, @extends MyColor<Red> 'fixes' the template type instead of propagating it to inheriting type. For example, in


@extends MyColor<Red>


/**
* @constructor
* @template T
*/
var A = function() { };

/** @param {T} t */
A.prototype.method = function(t) { };

/**
* @constructor
* @extends {A<string>}
*/
var B = function() { };

/**
* @constructor
*
* @extends {B<number>}
*/
var C = function() { };


var cc =new C();
var bb = new B();

var bm = bb.method("hello");
var cm = cc.method(1);



cc.method(1) will result in TYPE_MISMATCH: actual parameter 1 of A.prototype.method does not match formal parameter
found : number
required: string


cc.method(1)


TYPE_MISMATCH: actual parameter 1 of A.prototype.method does not match formal parameter
found : number
required: string



You can try changing your code to


/**
* @property {string} color
* @template {T}
*/
class MyColor {
constructor() {
this.color = 'unknown';
}

/**
* @returns {T}
*/
static makeColor() {
return /**@type {T}*/ new this.prototype.constructor();
}
}

/**
* @extends MyColor<T>
* @template {T}
*/
class Red extends MyColor {
constructor() {
super();
this.color = 'red';
}
}

const circle1 = Red.makeColor();

/**
* @extends Red<DarkRed>
*
*/
class DarkRed extends Red {
constructor() {
super();
this.level = 2;
}

darker() {
this.level += 1;
}
}

const circle = DarkRed.makeColor();



another possible solution is using @return {this} instead of @template (works since 2018.2):


@return {this}


@template


class MyColor {
constructor() {
this.color = 'unknown';
}

/**
* @return {this}
*/
static makeColor() {
return new this.prototype.constructor();
}
}


class Red extends MyColor {
constructor() {
super();
this.color = 'red';
}
}

class DarkRed extends Red {
constructor() {
super();
this.level = 2;
}

darker() {
this.level += 1;
}
}





This works for DarkRed, but Red.makeColor() will not recognize the return as Red.
– Comtaler
2 days ago


DarkRed


Red.makeColor()


Red





I guess you can't fix the type and propagate it to inheriting type at the same time using JSDoc:(
– lena
2 days ago





Then I guess it's a limitation of JSDoc, not WebStorm. Do you think there is other way to do it with JSDoc without using template?
– Comtaler
yesterday





you can remove all JSdoc comments and just use /** * @return {this} */ static makeColor() {}; but htis only works since 2018.2 (youtrack.jetbrains.com/issue/WEB-33061)
– lena
yesterday


/** * @return {this} */ static makeColor() {}





please update your answer and I will accept it. Thanks @lena
– Comtaler
yesterday






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Comments

Popular posts from this blog

paramiko-expect timeout is happening after executing the command

Opening a url is failing in Swift

Export result set on Dbeaver to CSV