如何使用JSDoc

时间:2019-06-09 16:30:53

标签: typescript recursion closures jsdoc

在一个使用香草JS的项目中,我有一个相当复杂的用例,并使用tsc检查类型,这些类型带有在JSDoc注释中编写的类型注释。我有一个返回函数的函数,返回的函数可以递归调用自身,同时还重新分配一些闭包变量。

这是一个愚蠢的例子,它弄清楚了要点,并且会抛出相同的错误:

/**
 * @returns {function(): number}
 */
function circular() {
  let num = Math.random();

  return function tryAgain() {
    if (num < 0.5) {
      return num;
    }

    num = Math.random();
    return tryAgain();
  };
}

因此,如果我使用tsc对此代码进行类型检查:

tsc --allowJs --checkJs --noEmit --strict --target ES2017 *.js

我收到以下错误:

error TS7023: 'tryAgain' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.

首先,此错误似乎非常错误。我显然有一个显式的返回类型注释,这是使用适当的TypeScript而不是JSDoc针对similar circular references提出的解决方案。

但是,我对任何解决方法都感到满意,因为它无需大量的重构即可删除闭包和/或递归,从而可以使其编译。我已经尝试了许多可能的解决方法,但都没有成功。

用注释包装return函数:

  return /** @type {function(): number} */ (function tryAgain() {
    . . .
  });

用注释包装递归调用:

    return /** @type {number} */ (tryAgain());

用强制包装递归调用:

    return Number(tryAgain());

在这一点上,我完全不了解如何正确地对此进行注释,或者至少如何使这些东西编译。

1 个答案:

答案 0 :(得分:1)

将函数定义与return分开可以注释tryAgain,从而消除了错误:

/**
 * @returns {function(): number}
 */
function circular() {
  let num = Math.random();

  /**
   * @returns {number}
   */
  function tryAgain() {
    if (num < 0.5) {
      return num;
    }

    num = Math.random();
    return tryAgain();
  }

  return tryAgain;
}

内联也可以:

/**
 * @returns {function(): number}
 */
function circular() {
  let num = Math.random();

  return /** @returns {number} */ function tryAgain() {
    if (num < 0.5) {
      return num;
    }

    num = Math.random();
    return tryAgain();
  };
};