VS 代码中的 jsDoc @callback

jsDoc @callback in VS Code

有什么方法可以在 VS Code 中使用 jsDoc 的 @callback 标签吗?

我尝试了从 jsDoc documentation of the callback tag 中截取的以下代码:

/**
 * @class
 */
function Requester() {}

/**
 * Send a request.
 * @param {requestCallback} cb - The callback that handles the response.
 */
Requester.prototype.send = function(cb) {
    // code
};

/**
 * This callback is displayed as a global member.
 * @callback requestCallback
 * @param {number} responseCode
 * @param {string} responseMessage
 */

但是 VS Code 似乎没有正确解释标签,你的参数类型仍然是 any 并且函数的工具提示中没有提到回调定义。

是否有启用此功能的解决方法/插件?

在撰写本文时,VSCode 不支持 @callback,但有解决方法(一旦 VSCode 支持回调,我将更新此答案以反映他们从哪个版本开始工作)。

查看此问题以跟踪进度:

[IntelliSense] [Salsa] doesn't recognize JSDoc callback parameter #7515

编辑 2018 年 5 月 8 日: 刚刚提交了带有修复的拉取请求:

Add callback tag, with type parameters

编辑 2018 年 5 月 17 日: 修复已合并到 TypeScript 2.9.1 中,可能会出现在 VS Code 的下一个版本中


建议使用 @typedef 的不完整解决方法 in an early comment in the thread:

/**
 * @typedef {function(number)} addedCallback
 */

/**
 *@param {addedCallback} a
 */
var add = function (a) { 

}

但是,正如后面的一些评论所述:

The real use of @callback is to properly describe all the parameters of the callback and sometimes the expected return value and its effect on the current function.

该评论还提供了两种更完整的解决方法:创建虚拟函数或记录回调本身。

如果您使用像 Webpack 这样的构建工具,并将其设置为消除未使用的变量和函数,"dummy" 函数将不会显示您的生产代码。

以下是两种解决方法的示例,基于 code of my own:

/**
 * A compare function to pass to `indices.sort()`, see also:
 * [`TypedArray.prototype.sort()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/sort).
 *
 * @param {number} i
 * @param {number} j
 */
function indexCompareFunction(i, j) {
  // dummy function for missing VSCode JSDoc callback support
  return i - j;
}

// Explicit
/**
 * Creates a compare function to sort a _separate_ array
 * of indices, based on lexicographical ordering of
 * the array values. Produces a stable sort.
 * @param {*[]} array
 * @returns {indexCompareFunction}
 */
function baseCompareFunc(array) {
  return (i, j) => {
    let vi = array[i],
      vj = array[j];
    return vi < vj ?
      -1 : vi > vj ?
        1 : i - j;
  };
}

// Inferred from callback JSDoc
/**
 * @param {*[]} array
 */
function baseCompareFunc2(array) {
  // Must store the function in a variable,
  // otherwise JSDoc does nothing!
  /**
   * @param {number} i
   * @param {number} j
   */
  let compareFunc = (i, j) => {
    let vi = array[i],
      vj = array[j];
    return vi < vj ?
      -1 : vi > vj ?
        1 : i - j;
  };
  return compareFunc;
}

编辑:还有另一个较短的解决方法,它依赖于 VSC 的 TypeScript 支持。它技术上不是"standard" JSDoc。自己决定这是否重要。正如其中一位开发人员所解释的那样:

inside { .. } we allow TypeScript type syntax, and that is how you define a call signature in TS.

/**
 * Creates a compare function for sorting a set of *indices*
 * based on lexicographical comparison of the array values
 * @param {*[]} array
 * @returns {{(i:number, j:number)=> number}}
 */
function baseCompareFunc(array) {
  return (i, j) => {
    let vi = array[i],
      vj = array[j];
    return vi < vj ?
      -1 :
      vi > vj ?
        1 :
        i - j; // the part that makes this a stable sort
  };
}