Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JsDoc, ES6 and @param {Constructor}

I am trying to use JsDoc to document es6 classes. Can't believe that you can't pass a class as a parameter (a class type, not an instance type).

I've been trying things but can't get this simple code to work so that JsDoc doesn't throw me some warnings.

I can't get it to work unless I create a @typedef for each of my classes, then add manually all own and inherited members to it. Can't even do a mixin!

Has anyone succeeded in passing a constructor/class parameter? So that JsDoc be in the static context, not the instance context?

/**
 * @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 issue : https://github.com/jsdoc3/jsdoc/issues/1088

like image 958
Ludovic C Avatar asked Oct 15 '15 14:10

Ludovic C


2 Answers

I've been running into same issue with auto-completion in WebStorm multiple times. While it looks like currently there is no straight-forward way in jsdoc to say that parameter is a reference to a constructor (not to an instance), there is a suggestion from JetBrains team to implement something like @param {typeof Constructor} (where typeof is from typescript) or @param {Constructor.} that was suggested by closure compiler team. You can vote for following issue to get your main concern with WebStorm autocompletion resolved - https://youtrack.jetbrains.com/issue/WEB-17325

like image 192
sergeyski.com Avatar answered Nov 15 '22 04:11

sergeyski.com


In Visual Studio Code, you can specify

@param {function(new:MyClass, SomeArgType, SecondArgType, etc...)}

I'm not sure what spec that syntax comes from or who else supports it, but it Works For Me.

like image 44
Coderer Avatar answered Nov 15 '22 06:11

Coderer