typescript - 如何使用 JSDoc 为递归闭包编写显式返回类型注释
问题描述
我在一个项目中有一个相当复杂的用例,它使用 vanilla 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的类似循环引用提出的解决方案。
但是我很高兴有任何解决方法可以在没有大量重构的情况下进行编译,从而消除闭包和/或递归。我已经尝试了许多可能的解决方法,但都没有奏效。
用注释包装返回函数:
return /** @type {function(): number} */ (function tryAgain() {
. . .
});
用注释包装递归调用:
return /** @type {number} */ (tryAgain());
用强制包装递归调用:
return Number(tryAgain());
在这一点上,我完全不知道如何正确地注释它,或者至少如何让该死的东西编译。
解决方案
将函数定义与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();
};
};
推荐阅读
- javascript - 为什么下面的代码只提取第一个图像的 ID 名称?
- ruby-on-rails - routes.rb 映射控制器名称创建问题
- dynamics-crm - 如何使用多个 Microsoft Forms 进行测验?
- jquery - 如果值存在则显示模态,如果不存在则显示错误消息
- python-3.x - Pandas 的年度总和和月平均值
- android - Volley String 请求响应(侦听器)错误
- linkedin - 使用 API 本地下载 LinkedIn Public Feeds (hashtag)
- c++ - 为什么 lambda 取变量的初始值
- ios - Populate table view from different Swift file
- ruby-on-rails - 在表中添加嵌套 json - rails