【问题标题】:Return types for recursive async generator function递归异步生成器函数的返回类型
【发布时间】:2021-07-11 20:13:15
【问题描述】:

定义以下递归异步函数生成器的正确类型是什么?

async function* recursive_f(n: number): AsyncGenerator<number, ?, ?> {
    n++
    if(n>0) {
        yield n
        return await recursive_f(n)
    }

    return Promise.resolve()
}

以下代码未按预期工作。它应该递归地减少 n 并产生一次负数,而不是通过 if 条件并结束。

async function* recursive_f(n: number): AsyncGenerator<number> {
    
    if (n < 0) {
        yield n
    }

    return await recursive_f(n--) // 'await' has no effect on the type of this expression.
}

async function main_function() {
    console.log(`main_function`)
    let num = 10
    for await (const n of recursive_f(num)) {
        console.log(n)
    }
}

main_function().then(console.log, console.error)

【问题讨论】:

  • 恐怕我不明白你想要达到什么目的;您希望recursive_f(10) 准确生成一组数字吗?只是-1吗?或者是从101 的所有数字,比如this?你为什么要递归调用函数而不是迭代?只是玩递归还是有一些实际用例?我现在比第一次问这个问题时更困惑???
  • 我需要recursive_f 来产生-1 但递归地减少n,我只是在这里玩,但我无法创建一个链来做到这一点
  • 好吧,this 你想要什么?如果可行,我将编辑我的答案。如果这不是你想要的,你能详细说明一下吗?请注意,使用yield* 操作符推迟到另一个生成器是最简单的,而不是尝试手动重新yield 结果。如果您必须这样做,这是可能的,例如this,但我不确定您为什么要这样做。另请注意,您实际上并没有在那里做任何异步操作,例如像this 这样的简单“睡眠”。我应该包括哪些(如果有的话)?

标签: typescript recursion types generator


【解决方案1】:

如果没有包含用例的 minimal reproducible example,我无法判断以下内容是否适合您的需求,因此请检查一下。


您可以像这样定义recursive type alias

type RecursiveF = AsyncGenerator<number, void | RecursiveF>;

这意味着:RecursiveF 是一个异步生成器函数,它产生 number,并返回 voidRecursiveF。在实践中这似乎很难使用,因为 void 类型的值不能真正被检查。但这取决于您和您的用例。

不管怎样,现在你可以用它来注释recursiveF的返回类型了:

async function* recursive_f(n: number): RecursiveF {
  n++
  if (n > 0) {
    yield n
    return recursive_f(n)
  }

  return Promise.resolve()
}

这在编译器同意的意义上是有效的。能不能满足你的需求,你自己看看。

Playground link to code

【讨论】:

  • 所以问题是编译器在遇到递归异步函数时无法推断返回类型?这不是缺少的功能吗?
  • 使用您的解决方案,编译器不再抱怨返回类型,但是当我将await 添加到第一个return 时,我得到'await' has no effect on the type of this expression
  • 如果您能提供一个 minimal reproducible example(尤其是 TS Playground 链接的形式)来演示该问题,那将非常有帮助。
  • 哦,我看到你编辑了这个问题;有机会我会看的
  • 我添加了一个mre
猜你喜欢
  • 1970-01-01
  • 2014-05-01
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多