避免打字稿抱怨永远不会被取消分配的未分配值

时间:2020-04-03 02:30:42

标签: typescript rxjs

所以我有一个功能,可以用作从同步可观察流中选择值的简写。

完整功能如下:

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在此示例中使用了两次。首先在同步流上获取值。第二次在异步流上并引发错误,并且不返回任何值。完美。)

1 个答案:

答案 0 :(得分:0)

因为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并使用其方法。

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