Angular保护管理员链接遇TS2345类型错误,请求解决
解决AngularFire中switchMap的TypeScript类型错误
错误信息
Argument of type '(user: any) => AngularFireObject | Observable' is not assignable to parameter of type '(value: any, index: number) => ObservableInput'.ts(2345) Argument of type '(user: any) => AngularFireObject | Observable' is not assignable to parameter of type '(value: any, index: number) => ObservableInput'. Type 'AngularFireObject | Observable' is not assignable to type 'ObservableInput'. Type 'AngularFireObject' is not assignable to type 'ObservableInput'.ts(2345)
相关代码
AuthService.ts
import { Injectable } from "@angular/core"; import { GoogleAuthProvider } from 'firebase/auth'; import { AngularFireAuth } from '@angular/fire/compat/auth'; import { Observable } from "rxjs/internal/Observable"; import firebase from 'firebase/compat/app'; import { ActivatedRoute, Router, RouterStateSnapshot } from "@angular/router"; import { switchMap, of } from "rxjs"; import { UserService } from "./user.service"; import { AppUser } from "./Models/app-user"; @Injectable({ providedIn: 'root' }) export class AuthService { [x: string]: any; user$: Observable<firebase.User|any> ; constructor(private afAuth:AngularFireAuth, private router:Router,private route: ActivatedRoute, private userService: UserService) { this.user$ = afAuth.authState; } login() { let returnUrl = this.route.snapshot.queryParamMap.get('returnUrl') || '/'; localStorage.setItem('returnUrl',returnUrl); this.afAuth.signInWithRedirect(new GoogleAuthProvider()); } logout(){ this.afAuth.signOut(); } isLoggedin(state:RouterStateSnapshot,route:RouterStateSnapshot){ this.user$?.subscribe(user =>{ if(user) return true; this.router.navigate(['/login'],{queryParams:{returnUrl:state.url}}); return false; }) } getAppUser(): Observable<AppUser> { return this.user$.pipe( switchMap((user) =>{ if (user) { return this.userService.get(user.uid); } return of(null); }) ); } }
错误代码段
getAppUser(): Observable<AppUser> { return this.user$.pipe( switchMap((user) =>{ if (user) { return this.userService.get(user.uid); } return of(null); }) ); }
UserService.ts
import { Injectable } from '@angular/core'; import { AngularFireDatabase, AngularFireObject } from '@angular/fire/compat/database'; import firebase from 'firebase/compat/app'; import { AppUser } from './Models/app-user'; @Injectable({ providedIn: 'root' }) export class UserService { constructor(private db : AngularFireDatabase) { } save(user: firebase.User){ this.db.object('/user/'+user.uid).update({ name: user.displayName, email:user.email }); } get(uid:String):AngularFireObject <AppUser>{ return this.db.object('/user/'+uid); } }
解决方案
错误根源在于AngularFireObject并非RxJS的Observable类型,而switchMap要求返回值必须是ObservableInput(包含Observable、Promise等)。要解决这个问题,需要将AngularFireObject转换为Observable,可通过其内置的valueChanges()方法实现。
方案一:修改UserService的get方法
直接让get方法返回Observable类型:
// UserService.ts get(uid: string): Observable<AppUser | null> { return this.db.object('/user/' + uid).valueChanges(); }
方案二:在AuthService中转换类型
如果不想修改UserService,可在switchMap中调用valueChanges():
// AuthService.ts getAppUser(): Observable<AppUser | null> { return this.user$.pipe( switchMap((user) => { if (user) { return this.userService.get(user.uid).valueChanges(); } return of(null); }) ); }
注意:原代码中getAppUser声明返回Observable<AppUser>,但实际可能返回null,建议将返回类型修正为Observable<AppUser | null>以符合TypeScript的类型检查规则。
内容的提问来源于stack exchange,提问作者Jayanatha Nanayakkara
相关产品推荐
相关产品推荐

