[英]How to map multiple Subject in an object literal to an object literal of corresponding Observable
我正在研究 Angular 中的 class 並想分享屬於該 class 的一堆狀態。 所以我做了一堆BehaviorSubject
private subjects = {
a : new BehaviorSubject<A>(this.a),
b : new BehaviorSubject<B>(this.b),
c : new BehaviorSubject<C>(this.c),
d : new BehaviorSubject<D>(this.d),
e : new BehaviorSubject<E>(this.e),
}
為了防止泄露主體的Observer
端並且只暴露Observable
端,我將主體設為私有並使用 observables 公開:
observables = {
a : this.subjects.a.pipe(share()),
b : this.subjects.b.pipe(share()),
c : this.subjects.c.pipe(share()),
d : this.subjects.d.pipe(share()),
e : this.subjects.e.pipe(share()),
}
我認為 observables 應該能夠從主題中生成,這樣當我想添加更多主題時,我不需要手動修改 observables。 就像是:
observables = (()=>{
let observables : {[Property in keyof typeof this.subjects]:Observable} = {}
for(let key in this.subjects)
{
observables[key] = this.subjects[key as keyof typeof this.subjects].pipe(share())
}
return observables;
})();
但是這里的Observable
和share
不知道它們的泛型類型。 我怎樣才能使這項工作或是否有更好的模式?
據我所知,您不需要share
BehaviorSubject
可觀察對象,因為它已經通過BehaviorSubject
很熱。
您可以使用Mapped types解決通用類型問題:
const subjects = {
a: new BehaviorSubject<number>(1),
b: new BehaviorSubject<string>('foo'),
c: new BehaviorSubject<boolean>(false),
};
// utility type to convert BehaviorSubject<T> to Observable<T>
// (can be inlined below instead)
type BehaviorSubjectToObservable<T> =
T extends BehaviorSubject<infer U> ? Observable<U> : never;
// create appropriate type for resulting object which has the same keys
// but maps to Observable<T>
// this ensures correct typing within the reduce
type Observables<T> = {
[P in keyof T]: BehaviorSubjectToObservable<T[P]>;
};
// transform the object
const observables = Object.entries(subjects).reduce(
(acc, [key, subject]) => ({ ...acc, ...{ [key]: subject.asObservable() } }),
{} as Observables<typeof subjects>,
);
// typeof observables.a = Observable<number>
// typeof observables.b = Observable<string>
// typeof observables.c = Observable<boolean>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.