Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jsdoc @typedef - how to declare function properly?

Here is my jsdoc declaration.

How should I adjust it, so that MyNewType.logFirst property actually references logFirst function, which I've annotated below?

// my-new-type.js
/**
 * MyNewType definition
 * @typedef {Object} MyNewType
 * @property {function} logFirst
 * @property {function} logSecond
 */

/**
 * @param {number} first
 * @param {number} second
 * @returns MyNewType
 */
module.exports = (first, second) => {
  /**
   * logs first argument
   * @param {number} times
   */
  function logFirst(times) {
    for (let i = 0; i < times; i++) {
      console.log(first);
    }
  }

  /**
   * logs second argument
   * @param {number} times
   */
  function logSecond(times) {
    for (let i = 0; i < times; i++) {
      console.log(second);
    }
  }

  return {
    logFirst,
    logSecond
  };
};

It's important, that we keep this kind of "factory" structure.

Currently - this is what I receive: enter image description here

I want my IDE to bind MyNewType.logFirst with logFirst definition.

like image 380
Pavel Polyakov Avatar asked Nov 07 '18 14:11

Pavel Polyakov


1 Answers

Unless I'm mistaken, I don't see how the upvoted solution could ever work.

There is nothing like @typedef {MyNewType} MyNewTypein JSDoc, but rather @typedef {Object} MyNewType (to define the base type) (see docs)

Also, annotations are all mixed up in the given solution. For example, @param is only for function parameters and when declaring a specialized function type (see docs)

Last but not least, no offence but the upvoted solution is also wrong because it mixes up the var MyNewType type declaration (a function with two parameters and returning an object with two properties) and the actual returned value declaration (the two properties of the said object). In addition to not including the required brackets around the returned type.

EDIT: oh, I forgot that logFirst is not a number but a Function, which is another mistake in the solution proposed by the OP colleague.

I really cannot fathom why people would upvote such a broken solution...

Being by no means expert in JSDoc, I however think the following solution should fix all that, for new SO visitors:

(NOTE: I don't see why we would ever need two different typedef for the logFirst and logSecond functions as they have the exact same signature, but JFF I specified both)

/**
 * Declare our "logFirst" type (which is a function)
 *
 * @callback TypeFnLogFirst
 * @param {number} times
 * @returns {void}
 */

/**
 * Declare our "logSecond" type (which is a function)
 *
 * @callback TypeFnLogSecond
 * @param {number} times
 * @returns {void}
 */

/**
 * Declare our returned type
 * 
 * @typedef {Object} TypeObjTwoFns
 * @property {TypeFnLogFirst} logFirst
 * @property {TypeFnLogSecond} logSecond
 */

/**
 * Declare our "MyNewType" type (which is a function)
 *     with two parameters
 *     and a return value (object literal of type TypeObjTwoFns)
 *     (==> where the magic happens)
 * Note that "[at]typedef Function" is the same as "[at]callback" (as per the docs)
 *
 * @typedef {Function} TypeFnNewType
 * @param {*} first
 * @param {*} second
 * @returns {TypeObjTwoFns}
 */

/** @type {TypeFnNewType} MyNewType */
var MyNewType = (first, second) => {
    /** @type {TypeFnLogFirst} logFirst */
    function logFirst(times) {
        for (let i = 0; i < times; i++) {
            console.log(first);
        }
    }

    /** @type {TypeFnLogSecond} logSecond */
    function logSecond(times) {
        for (let i = 0; i < times; i++) {
            console.log(second);
        }
    }

    return {
        logFirst,
        logSecond
    };
};

Source: JSDoc typedef,callback,param and JSDoc member,var,type

like image 188
Lideln Kyoku Avatar answered Sep 20 '22 08:09

Lideln Kyoku