在一个使用香草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());
在这一点上,我完全不了解如何正确地对此进行注释,或者至少如何使这些东西编译。
答案 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();
};
};