3

我是 Angular 的新手。

我怎么解决这个问题?

我已经安装了 AngularCLI: 11.0.7和 Node:12.18.4

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

ng g guard auth --skip-tests

错误:

错误:src/app/_guards/auth.guard.ts:15:5 - 错误 TS2322:类型 'Observable<true | undefined>' 不可分配给类型 'Observable'。输入'布尔| 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!')
      })
    )
  }
  
}
4

3 回答 3

5

可能是因为未定义时运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!')
      })
    )
  }
}
于 2021-01-28T13:29:25.593 回答
0

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

      map(user => {
        if (!user) {
          this.toastr.error('You shall not pass!')
        }
        return !!user;
      })
    )
于 2021-01-28T14:17:17.550 回答
0

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

错误:src/app/_guards/auth.guard.ts:15:5 - 错误 TS2322:类型 'Observable<true | 未定义>

这意味着您尝试从具有可以返回的特定类型列表的守卫返回 NOT BOOLEAN(在这种情况下为未定义)。即: Observable<boolean | 网址树> | 承诺<boolean | 网址树> | 布尔值 | 网址树。如您所见,根本没有 UNDEFINED。您没有为所有“分支”指定退货。这就是你的情况。简单地说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$时,它可能是未定义的情况。最新的 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;
          })
    
        );

  }
于 2021-11-14T17:02:31.083 回答