使用 Angular 路由 Guard 时:'Observable<true | undefined>' 不可分配给类型 > 'Observable<boolean>'
When using an Angular route Guard: 'Observable<true | undefined>' is not assignable to type > 'Observable<boolean>'
我是 Angular 的新手。
我该如何解决这个问题?
我已经安装了 Angular CLI: 11.0.7
和节点:12.18.4
我已经安装了一个Angular路由守卫:
ng g guard auth --skip-tests
错误:
Error: src/app/_guards/auth.guard.ts:15:5 - error TS2322: Type
'Observable<true | undefined>' is not assignable to type
'Observable'.
Type 'boolean | undefined' is not assignable to type 'boolean'.
Type 'undefined' is not assignable to type '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!')
})
)
}
}
可能是因为当 user
未定义时,return 运算符未从 map
编辑任何内容。尝试return一些东西
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!')
})
)
}
}
您可以使用双非运算符 return 该值。在这两种情况下都发出一个具有确定值的值很重要,无论是真还是假。
map(user => {
if (!user) {
this.toastr.error('You shall not pass!')
}
return !!user;
})
)
我有类似的问题。那是因为 Typescript 在最新版本中强制执行了一些输入。当你得到:
错误:src/app/_guards/auth.guard.ts:15:5 - 错误 TS2322:类型 'Observable
这意味着您尝试 return NOT BOOLEAN - 在这种情况下 undefined - 来自具有特定类型列表的守卫 return。即:Observable |承诺<布尔值 |网址树> |布尔 |网址树 。如您所见,根本没有 UNDEFINED。
您没有为所有 'branches' 指定 return。那是你的情况。简单的说 return 真假真清楚。
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$ 上给用户输入了错误的类型 |空。
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;
})
);
}
我是 Angular 的新手。
我该如何解决这个问题?
我已经安装了 Angular CLI: 11.0.7
和节点:12.18.4
我已经安装了一个Angular路由守卫:
ng g guard auth --skip-tests
错误:
Error: src/app/_guards/auth.guard.ts:15:5 - error TS2322: Type 'Observable<true | undefined>' is not assignable to type 'Observable'. Type 'boolean | undefined' is not assignable to type 'boolean'. Type 'undefined' is not assignable to type '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!')
})
)
}
}
可能是因为当 user
未定义时,return 运算符未从 map
编辑任何内容。尝试return一些东西
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!')
})
)
}
}
您可以使用双非运算符 return 该值。在这两种情况下都发出一个具有确定值的值很重要,无论是真还是假。
map(user => {
if (!user) {
this.toastr.error('You shall not pass!')
}
return !!user;
})
)
我有类似的问题。那是因为 Typescript 在最新版本中强制执行了一些输入。当你得到:
错误:src/app/_guards/auth.guard.ts:15:5 - 错误 TS2322:类型 'Observable
这意味着您尝试 return NOT BOOLEAN - 在这种情况下 undefined - 来自具有特定类型列表的守卫 return。即:Observable
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$ 上给用户输入了错误的类型 |空。
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;
})
);
}