【问题标题】:Angular, observable pipe limit?有角度的,可观察的管道限制?
【发布时间】:2021-11-14 12:50:38
【问题描述】:

我正在我的一个路线守卫中这样做......

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
    // go through each check sequentially, stop process if one does throwError
    return of(true).pipe( // Is there a limit to operators in a pipe???
      switchMap(() => of(true)), // simplified for this post...usually call a function that returns
      switchMap(() => of(true)),
      switchMap(() => of(true)),
      switchMap(() => of(true)),
      switchMap(() => of(true)),
      switchMap(() => of(true)),
      switchMap(() => of(true)),
      switchMap(() => of(true)),
      // if any function returns throwError, we skip other checks
      catchError(() => of(false))
    );
  }

我遇到了错误。如果列表中再添加一个 switchMap,VSCode 会告诉我... “类型 'Observable' 不可分配给类型 'Observable'。 类型 '{}' 不可分配给类型 'boolean'.ts(2322)"

有人可以向我解释为什么会这样吗?想不通,找不到相关问题。

【问题讨论】:

    标签: angular visual-studio-code rxjs-observables


    【解决方案1】:

    this github issue 对此进行了很好的解释。

    它的要点是只支持 9 个运算符 - 不再支持,它将回退到类型 Observable&lt;{}&gt;,因为他们必须手动键入最多 9 个运算符的所有内容。

    使用多个管道(在第 9 个条目后保持类型安全)

    如果你仍然想保持类型安全但添加超过 9 个运算符,只需再次调用管道函数即可。

    source$
      .pipe(
        tap(() => {}),
        tap(() => {}),
        tap(() => {}),
        tap(() => {}),
        tap(() => {}),
        tap(() => {}),
        tap(() => {}),
        tap(() => {}),
        tap(() => {})
      )
      .pipe(
        // Add the next operators after the 9nth here
        tap(() => {}) 
      )
    

    手动断言结果类型

    或者,您可以在末尾添加手动类型断言。但请注意:在第 9 个运算符之后,类型将被推断为 Observable&lt;{}&gt;,实际上失去了类型安全性。

    const source$:Observable<boolean> = of(true)
      .pipe(
        tap(() => {}),
        tap(() => {}),
        tap(() => {}),
        tap(() => {}),
        tap(() => {}),
        tap(() => {}),
        tap(() => {}),
        tap(() => {}),
        tap(() => {}),
        // Typesafety is lost here
        tap(() => {}),
        tap(() => {}),
    
      // Manually assert the type at the end 
      // Beware that the compiler will allow pretty much anything here,
      // so "as Observable<string>" would work, even though it'd be wrong.
      ) as Observable<boolean>;
    

    【讨论】:

    • 不需要,这与将所有内容都放在一个管道中的行为完全相同。这只需要获得正确的类型推断。
    • 那么就在第二个管道中放一个catchError?
    • 如果你想让 catchError 成为你的 observable 做的最后一件事(如上面的例子),是的。
    • 对不起。我应该在帖子中更清楚......这些 switchMap 中的每一个都将返回 of(true) 或 throwError();
    • 我个人不喜欢这种解决方案,因为它会停止管道中的类型推断链——基本上在第 9 个条目之后会失去所有类型安全。我可以在链接中包含建议:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-29
    • 1970-01-01
    • 2020-02-02
    • 1970-01-01
    相关资源
    最近更新 更多