【问题标题】:How to map multiple Subject in an object literal to an object literal of corresponding Observable如何将对象文字中的多个 Subject 映射到相应 Observable 的对象文字
【发布时间】:2022-08-19 19:02:28
【问题描述】:

我正在使用 Angular 中的一个类,并希望分享属于该类的一堆状态。所以我做了一堆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 = {
    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;
})();

但是这里Observableshare 不知道它们的泛型类型。我怎样才能使这项工作或是否有更好的模式?

    标签: angular typescript rxjs observable


    【解决方案1】:

    据我所知,您不需要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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-06
      • 2018-09-22
      • 2019-01-25
      • 1970-01-01
      • 2016-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多