【问题标题】:When using an Angular route Guard: 'Observable<true | undefined>' is not assignable to type > 'Observable<boolean>'使用 Angular 路由守卫时:'Observable<true | undefined>' 不可分配给类型 > 'Observable<boolean>'
【发布时间】:2021-05-02 09:38:09
【问题描述】:

我是 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'。 类型“未定义”不能分配给类型“布尔”。

 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 => {
             ~~~~~~~~~

守则:

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!')
      })
    )
  }
  
}

【问题讨论】:

    标签: angular angular-router-guards angular-guards


    【解决方案1】:

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

    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!')
          })
        )
      }
    }
    

    【讨论】:

    • 第一个解决方案对我有用。谢谢!!!
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      我有类似的问题。那是因为 Typescript 强制在最新版本中输入一些内容。当你得到:

      错误:src/app/_guards/auth.guard.ts:15:5 - 错误 TS2322:类型 'Observable

      这意味着您尝试返回 NOT BOOLEAN - 在这种情况下 undefined - 从具有特定类型列表的守卫可以返回。即:Observable |承诺 |布尔值 |网址树。如您所见,根本没有 UNDEFINED。 您没有为所有“分支”指定 return。这就是你的情况。简单地说return true or false real clear。

        map(user => {
          if (user) return true; // HERE YOU RETURNED TRUE 
          this.toastr.error('You shall not pass!')
          // HERE YOU DID NOT RETURNED return false;
          // from where interpreter should know what should be return 
          // when user is FALSE? ... it is not specified. Isn't it ?
        })
      

      关于 Udemy 的培训还有一个问题。当您定义 this.accountService.currentUser$ 时,它可能是 undefined 的情况。最新的 Typescript 不喜欢不明确的类型——什么才是真正的好东西。

      在我的例子中,我在 this.accountService.currentUser$ 上给 User | 输入了错误的类型。空。

        private currentUserSource = new ReplaySubject<User | null>(1);
        currentUser$ = this.currentUserSource.asObservable();
      

      Null 我收到了 USER 或 NULL 在条件 !null 导致它没有进入条件。 undefined 的情况完全相同。我的解决方案如下:

             canActivate(): Observable<boolean>  {
              return this.accountService.currentUser$.pipe(
                tap(user => { 
                  if (user === null) this.toastr.error('You shall not pass!');
         // your case should be:
        // if (user === undefined) this.toastr.error('You shall not pass!');
                }),
                map((user: any) => {
                 return user ? true : false;
                })
          
              );
      
        }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-08-17
        • 1970-01-01
        • 2019-05-21
        • 1970-01-01
        • 1970-01-01
        • 2017-06-29
        • 2016-11-12
        相关资源
        最近更新 更多