JsDoc, ES6 and @param {Constructor}

5
我正在尝试使用JsDoc记录es6类。令人难以置信的是,你不能将一个类作为参数传递(一个类类型,而不是实例类型)。
我试过很多方法,但无法让这个简单的代码工作,以便JsDoc不会给我一些警告。
除非我为我的每个类创建一个@typedef,然后手动添加所有自己的和继承的成员,否则我无法让它正常工作。甚至无法进行混入!
有没有人成功地传递构造函数/类参数?这样JsDoc就在静态上下文中,而不是实例上下文中?
/**
 * @class A
 */
class A {

    /**
     * @static
     */
    static helloFromClassA(){
    }
}

/**
 * @class B
 * @extends A
 */
class B extends A{

    /**
     * @static
     */
    static helloFromClassB(){
    }
}

/**
 * Class as object
 * @param {A} ClassArgument
 */
function fn1(ClassArgument){
    ClassArgument.helloFromClassA(); // Unresolved function or method helloFromClassA
    // Does not work because ClassArgument is interpreted as an
    // instance of A, not A's constructor
}

/**
 * // Class as function
 * @param {Function} ClassArgument
 */
function fn2(ClassArgument){
    ClassArgument.helloFromClassA(); // Unresolved function or method helloFromClassA
    // Does not work because ClassArgument is interpreted as an
    // empty function, not A's constructor
}

/**
 * // Type definition
 * @typedef {Object} AClass
 * @property {Function} helloFromClassA
 * @property {Function} super
 */

/**
 * // Trying to mixin the AClass
 * @typedef {Object} BClass
 * @property {Function} helloFromClassB
 * @mixes {AClass}
 * @mixes {A}
 */

/**
 * // Adding manually all members
 * @typedef {Object} BClass2
 * @property {Function} helloFromClassB
 * @property {Function} helloFromClassA
 */

/**
 * @param {BClass} ClassArgument
 */
function fn3(ClassArgument){
    ClassArgument.helloFromClassA(); // Unresolved function or method helloFromClassA
    // Does not work because the BClass typedef does not take
    // into account the mixin from AClass, nor from A
    ClassArgument.helloFromClassB(); // No warming
}

/**
 * @param {BClass2} ClassArgument
 */
function fn4(ClassArgument){
    ClassArgument.helloFromClassA(); // No Warning
    ClassArgument.helloFromClassB(); // No warming
    // Works because we manually defined the typedef with all own
    // and inherited properties. It's a drag.
}


fn1(B);

fn2(B);

fn3(B);

fn4(B);

jsDoc问题: https://github.com/jsdoc3/jsdoc/issues/1088


(意思是:有一个关于jsDoc的问题,详情请查看链接)

你已经将这些方法声明为 static - 在实例上调用它们将起作用,但在我看来,这是关键字的一个有点奇怪的用法。 - CodingIntrigue
2
什么意思?ES6有静态关键字,允许您在构造函数上声明方法,而不是在原型上声明。这些是静态方法。我并不是试图在实例上调用它们,而是在构造函数上调用。问题在于JsDoc不允许您将参数声明为构造函数(类型),它只允许您将参数声明为实例。 - Ludovic C
我明白了。我错误地认为val是一个实例,而不是对函数的引用。 - CodingIntrigue
是的,我也这么想,所以我更新了代码。 - Ludovic C
3个回答

3
我在WebStorm中遇到了自动完成的问题。虽然目前似乎在jsdoc中没有直接表明参数是引用构造函数(而不是实例)的方法,但JetBrains团队建议实现类似于@ param {typeof Constructor}(其中typeof来自typescript)或@ param {Constructor. },这是由闭包编译器小组提出的建议。您可以投票支持以下问题,以解决WebStorm自动完成的主要问题 - https://youtrack.jetbrains.com/issue/WEB-17325

3
在Visual Studio Code中,你可以指定
@param {function(new:MyClass, SomeArgType, SecondArgType, etc...)}

我不确定这个语法是来自哪里或者还有谁支持它,但是对我来说它可行。


1
typescript和google closure都支持使用{typeof SomeClass}来引用类作为类型(而不是类实例)。不幸的是,jsdoc不支持这种语法,将无法编译它(https://github.com/jsdoc3/jsdoc/issues/1349)。
因为我想要使用typescript对我的JavaScript进行类型检查,并且还想生成文档,所以我制作了这个jsdoc插件,将类似{typeof SomeClass}的表达式转换为{Class<SomeClass>},这样我就可以同时拥有两者:https://github.com/cancerberoSgx/jsdoc-typeof-plugin

1
这也被WebStorm所理解,详情请参见https://youtrack.jetbrains.com/issue/WEB-10214。 - manuc66

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接