jsdoc @typedef - 如何正确声明函数?

29

这是我的jsdoc声明。

我该如何调整它,以便MyNewType.logFirst属性实际上引用我下面注释的logFirst函数?

// 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
  };
};

保持这种“工厂”结构非常重要。

目前 - 我收到的是: enter image description here

我想让我的IDE将MyNewType.logFirstlogFirst定义绑定。

3个回答

41

除非我错了,否则我不认为被投票赞同的解决方案能够运行。

JSDoc中没有类似于@typedef {MyNewType} MyNewType的内容,而是使用@typedef {Object} MyNewType(以定义基本类型)(见文档

此外,在给定的解决方案中,注释混在一起。例如,@param仅用于函数参数和声明专门的函数类型(见文档

最后但并非最不重要的是,不冒犯,但被投票赞同的解决方案也是错误的,因为它混淆了var MyNewType类型声明(一个具有两个参数并返回两个属性的对象的函数)和实际返回值声明(所述对象的两个属性)。此外还需要在返回类型周围包括必需的括号。

编辑:哦,我忘记logFirst不是number而是Function,这是OP同事提出的另一个错误。

我真的无法理解为什么人们会投票赞同这样一个错误的解决方案...

虽然我并不是JSDoc专家,但我认为以下解决方案应该可以解决所有问题,适用于新的SO访问者:

(注意:我不明白为什么我们需要两个不同的typedef来分别定义logFirst和logSecond函数,因为它们具有完全相同的签名,但对此进行说明)

/**
 * 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
    };
};

来源: JSDoc typedef,callback,paramJSDoc member,var,type


1
请注意,"[at]typedef Function"与"[at]callback"(根据文档)是相同的 - 文档中是否明确提到了这一点?在智能感知方面,vscode似乎没有将它们视为相同的,因此只是想确认一下。 - gaurav5430

5

如果有帮助的话,我想对于一些人来说这很有用,因为OP是我的同事:

    // my-new-type.js
/**
 * MyNewType definition
 * @typedef {MyNewType} MyNewType
 * @param {number} first
 * @param {number} second
 * @property {function} logFirst
 * @property {function} logSecond
 * @returns MyNewType
 */

var MyNewType = module.exports = (first, second) => {
    /**
     * logs first argument
     * @typedef {number} logFirst
     * @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
    };
};

这对我们来说运作良好。

3
你的typedef应该是@typedef {function} MyNewType吗?在typedef声明之前,MyNewType未被定义,因此不能用作类型。但在另一个typedef中可以使用它。 - yuyu5

3

只有使用TypeScript作为类型检查器时,我认为存在一种更简单的解决方案:

/** @typedef { (first: number, second: number) => 
{logFirst: (time: number) => void, logSecond: (time : number) => 
void}} MyNewType */

/** @type { MyNewType } */
var MyNewType = module.exports = (first, second) => {
   ...
}

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