I'm working on an Angular service where I'm using BehaviorSubject to manage an IdentityToken. The BehaviorSubject is instiantiated as BehaviorSubject<IdentityToken | null>
. Then I derive a new observable from the BehaviorSubject by calling .asObservable()
. However, when I hover the derived observable then Typescript infers it as BehaviorSubject<IdentityToken>
. It seems to omit the null
. From my understanding the derived observable should be the same as the BehaviorSubject.
The relevant code:
private identityToken = new BehaviorSubject<IdentityToken | null>(
null
);
public identityToken$ = this.identityToken.asObservable(); // hovering the `identityToken$` typescript infers is as `BehaviorSubject<IdentityToken>`
The full code:
import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';
import { StorageKeys } from '../_models/localStorageKeys';
import { map } from 'rxjs/operators';
interface IdentityToken {
Role: string;
Permissions: string[];
}
@Injectable({
providedIn: 'root',
})
export class UserService {
private identityToken = new BehaviorSubject<IdentityToken | null>(
null
);
public identityToken$ = this.identityToken.asObservable(); // hovering the `identityToken$` typescript infers is as `BehaviorSubject<IdentityToken>`
public isAuthenticated$ = this.identityToken$.pipe(
map((token) => !!token)
);
constructor() {
this.identityToken = new BehaviorSubject<IdentityToken | null>(
this.getStoredToken()
);
}
private getStoredToken(): IdentityToken | null {
const stored = localStorage.getItem(StorageKeys.IDENTITY_TOKEN);
if (!stored) return null;
try {
return JSON.parse(stored);
} catch (e) {
localStorage.removeItem(StorageKeys.IDENTITY_TOKEN);
return null;
}
}
}
This is due to strictNullChecks
being false
(or unset) in your tsconfig
.