首页 > 解决方案 > 避免 Typescript 抱怨永远不会被分配的未分配值

问题描述

所以我有一个函数可以作为从同步可观察流中选择值的简写。

完整的函数如下所示:

export function select<T>(inStream: Observable<T>): T {
  let value: T;

  race(
    inStream,
    throwError(
      new Error(
        select.name + " expects a synchronous stream. Received an asynchronous stream."
        )
      )
    )
    .pipe(take(1))
    .subscribe(val => {
      value = val;
    });

  return value;  
}

如果 inStream 不同步,它会按预期工作并引发错误,这意味着我要么总是获得最新/当前发射中的值,要么出现错误。

但是打字稿抱怨在分配值之前正在使用该值。我可以理解 Typescript 不够聪明,无法了解我如何强制同步或错误,并且测试表明,当流实际上是同步的时,该值将始终正确设置,否则我们会收到错误。

那么我应该如何避免这个愚蠢的 Typescript-derp 呢?我不太想忽略它,但如果没有人有任何好的建议,我会考虑这个。

总之感谢!

(演示显示功能按预期工作,因此我们可以专注于解决打字稿解决方案,而不是被我正在使用的代码所牵制:

https://stackblitz.com/edit/rxjs-select-demo?file=index.ts

在此示例中使用了两次 select。首先在同步流上并获取值。第二次在异步流上抛出错误并且不返回任何值。完美的。)

标签: typescriptrxjs

解决方案


因为subscribe通常期望异步使用,我认为最干净的解决方案是将其转换为 Promise 并返回该 Promise:

export function select<T>(inStream: Observable<T>): Promise<T> {
    return race(
        inStream,
        throwError(
            new Error(
                select.name + " expects a synchronous stream. Received an asynchronous stream."
            )
        )
    )
        .pipe(take(1))
        .toPromise();
}

当然,您还.then需要awaitselect.

如果这更适合您的用例,您也可以返回 observable 并使用它的方法。

如果/当您需要调整它以与异步流一起使用时,这也使代码更具可扩展性。


推荐阅读