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;
}
}
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.
This works for
DarkRed
, butRed.makeColor()
will not recognize the return asRed
.– Comtaler
2 days ago