使用gapi auth2谷歌登录时如何解决null不可赋值给GoogleUser类型参数报错
报错根因
你声明的ReplaySubject泛型仅允许接收gapi.auth2.GoogleUser类型的参数,但是在登录失败、登出成功的逻辑中,你传入了null,和声明的类型不匹配,因此TypeScript抛出类型校验错误。
解决方法
这里提供3种适配不同场景的方案,优先推荐第一种:
- 方案1:修改泛型允许空值(最贴合业务逻辑)
将Subject的泛型扩展为允许null类型,同时调整observable方法的返回值类型即可,修改后的代码如下:
import { ReplaySubject, Observable } from 'rxjs'; export class GoogleSiginService { private auth2!: gapi.auth2.GoogleAuth // 扩展泛型允许null值 private subject = new ReplaySubject<gapi.auth2.GoogleUser | null>(1) constructor() { gapi.load('auth2',()=> { this.auth2 = gapi.auth2.init( { client_id:'184******' } ) }) } public sigin(){ this.auth2.signIn({ scope:'https://www.googleapis.com/auth/gmail.readonly' }).then(user => { this.subject.next(user) }).catch( ()=> { this.subject.next(null) }) } public signOut() { this.auth2.signOut().then(()=> { this.subject.next(null) }) } // 同步修改返回值类型 public observable(): Observable<gapi.auth2.GoogleUser | null> { return this.subject.asObservable() } }
后续订阅该可观察对象时,直接判断返回值是否为null即可识别当前登录状态。
- 方案2:使用undefined代替null(适配禁用null的项目规范)
如果你的项目TS规范中禁止使用null,可以将泛型扩展为允许undefined,同时把所有next(null)替换为next(undefined):
// 泛型声明 private subject = new ReplaySubject<gapi.auth2.GoogleUser | undefined>(1) // 调用处替换 this.subject.next(undefined) // observable返回值同步修改 public observable(): Observable<gapi.auth2.GoogleUser | undefined>
- 方案3:走RxJS错误通道传递异常(适配需要区分错误类型的场景)
如果你不需要通过next传递未登录状态,可以将异常事件通过error通道抛出,这种情况不需要修改泛型,但订阅时需要额外处理error回调:
// 登录失败处 .catch(() => { this.subject.error(new Error('谷歌账号登录失败')) }) // 注意:登出场景不推荐用error,会导致流直接终止,无法继续接收后续登录状态变更
内容的提问来源于stack exchange,提问作者ingmbk
相关产品推荐
相关产品推荐

