带有 rxjs 问题的 Angular 11 - TS2769:没有与此调用匹配的重载

时间:2021-03-09 17:26:58

标签: angular typescript rxjs angular11

我想订阅 Angular 11 中的 NavigationEnd 事件,同时使用来自 rxjs 的过滤器。

subscribe((event: NavigationEnd) ... 部分导致以下问题

目前的解决方案:

<块引用>

TS2769:没有与此调用匹配的过载。重载 1 of 5, '(observer?: NextObserver | ErrorObserver | CompletionObserver | undefined): Subscription',出现以下错误。 “(事件:NavigationEnd)=> void”类型的参数不可分配给“NextObserver |”类型的参数错误观察者 |完成观察者 |不明确的'。 '(event: NavigationEnd) => void'类型缺少属性'complete',但'CompletionObserver'类型需要。重载 2 of 5, '(next?: ((value: Event) => void) | undefined, error?: ((error: any) => void) | undefined, complete?: (() => void) |未定义):订阅',出现以下错误。 “(event: NavigationEnd) => void”类型的参数不可分配给“(value: Event) => void”类型的参数。参数“事件”和“值”的类型不兼容。 “事件”类型不能分配给“导航结束”类型。 “RouterEvent”类型中缺少“urlAfterRedirects”属性,但“NavigationEnd”类型中需要该属性。

请参阅下面提到的代码片段的构造函数代码:

export class NavigationService implements OnDestroy {
  private readonly routeChange: Subscription | undefined;
  private previousUrl: string | undefined;
  private ignoredRoutes = ['/signup', '/login', '/reset'];

  constructor(private router: Router) {
    this.routeChange = router.events
      .pipe(filter(event => event instanceof NavigationEnd))
      .subscribe((event: NavigationEnd) => {
        if (!this.ignoredRoutes.includes(event.url)) {
          this.previousUrl = event.url;
        }
      });
  }

  ngOnDestroy(): void {
    if (this.routeChange) {
      this.routeChange.unsubscribe();
    }
  }

  public routeToPreviousContent(): void {
    //route home if undefined
    const targetUrl = this.previousUrl ? this.previousUrl : '';
    this.router.navigate([targetUrl]).then();
  }
}

TS2769 在这种情况下是否有效?我认为带有 event instanceof NavigationEnd 的 rxjs 过滤器管道根本无法识别?!

1 个答案:

答案 0 :(得分:1)

传递给 filter 的函数不是类型保护,但您可以这样指定类型:

constructor(private router: Router) {
  this.routeChange = router.events
    .pipe(
      filter((event): event is NavigationEnd => event instanceof NavigationEnd)
    )
    .subscribe(event => {
      // "event" here is now of type "NavigationEnd"
    });
}