使用 Angular 路由保护时:'Observable<true | undefined>' 不可分配给 type > 'Observable<boolean>'

问题描述

我是 Angular 的新手。

我该如何解决这个问题?

我已经安装了 Angular CLI: 11.0.7 和 Node:12.18.4

我已经安装了一个 Angular 路由保护器:

ng g guard auth --skip-tests

错误

错误:src/app/_guards/auth.guard.ts:15:5 - 错误 TS2322:类型 '可观察' 不可分配给类型 '可观察'。 输入'布尔值| undefined' 不能分配给类型 'boolean'。 类型 'undefined' 不能分配给类型 'boolean'。

 15     return this.accountService.currentUser$.pipe(
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 16       map(user => {
    ~~~~~~~~~~~~~~~~~~~
...
 19       })
    ~~~~~~~~
 20     )
    ~~~~~
src/app/_guards/auth.guard.ts:16:11 - error TS7030: Not all code paths return a value.

16       map(user => {
             ~~~~~~~~~

guard

代码

import { Injectable } from '@angular/core';
import { CanActivate,ActivatedRouteSnapshot,RouterStateSnapshot,UrlTree } from '@angular/router';
import { ToastrService } from 'ngx-toastr';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { AccountService } from '../_services/account.service';

@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate {
  constructor(private accountService: AccountService,private toastr: ToastrService) {}

  canActivate(): Observable<boolean> {
    return this.accountService.currentUser$.pipe(
      map(user => {
        if (user) return true; // the problem occurs here!
        this.toastr.error('You shall not pass!')
      })
    )
  }
  
}

解决方法

可能是因为当 map 未定义时,user 运算符没有返回任何内容。尝试返回一些东西

export class AuthGuard implements CanActivate {
  constructor(private accountService: AccountService,private toastr: ToastrService) {}

  canActivate(): Observable<boolean> {
    return this.accountService.currentUser$.pipe(
      map(user => {
        if (user) return true;
        this.toastr.error('You shall not pass!');
        return false;
      })
    )
  }
}

或者更好的是,您可以使用 tap 运算符代替 map 来执行“toastr”通知等副作用。

export class AuthGuard implements CanActivate {
  constructor(private accountService: AccountService,private toastr: ToastrService) {}

  canActivate(): Observable<boolean> {
    return this.accountService.currentUser$.pipe(
      tap(user => {
        if (!user) this.toastr.error('You shall not pass!')
      })
    )
  }
}
,

您可以使用双非运算符来返回值。在这两种情况下都发出一个具有确定值(真或假)的值很重要。

      map(user => {
        if (!user) {
          this.toastr.error('You shall not pass!')
        }
        return !!user;
      })
    )