首页 > 解决方案 > 使用多个接口声明 BehaviorSubject 时如何访问所有属性?

问题描述

我有几个接口如下:

export interface INT1 {
   prop1: string;
   prop2: string;
}

export interface INT2 {
   prop1: string;
   prop3: string;
}

export interface INT3 {
   prop1: string;
   prop4: string;
}

现在我试图声明一个BehaviorSubject返回上述三个接口之一的 a:

private _mySub$ = new BehaviorSubject<INT1 | INT2 | INT3>(undefined);

这不起作用,因为如果我访问该BehaviorSubject值,我只会找到共享属性(在这种情况下只有prop1)。我究竟做错了什么?

标签: typescriptgenericsrxjs

解决方案


代码没有问题。由于_mySub$可能是,或BehaviorSubject类型的 a ,静态分析只能保证在所有情况下都具有属性。在不缩小类型的情况下推断其他属性的存在是不正确的。INT1INT2INT3_mySub$prop1

如果您知道对于特定上下文,BehaviorSubject总是会返回恰好其中一个接口,那么您可以使用更具体的声明,例如:

private _mySub$ = new BehaviorSubject<INT1>({prop1: '1', prop2: '2'});

类型警卫

处理广泛类型定义的一个常见解决方案是使用TypeScript Type Guards

示例:INT1 的用户定义类型保护

function instanceOfINT1(object: any): object is INT1 {
  return 'prop2' in object;
}

使用类型保护,您可以prop2BehaviorSubject发出时安全地访问INT1

class MyClass {
  private _mySub$ = new BehaviorSubject<INT1 | INT2 | INT3>({prop1: '1', prop2: '2'});

  constructor() {
    this._mySub$.subscribe( (val) => {
      if (instanceOfINT1(val)) {
        console.log(`val.prop2: ${val.prop2}`);
      }
    });
  }
}

推荐阅读