简体   繁体   English

RxJS 自定义运算符与 typescript 联合类型

[英]RxJS Custom operator with typescript Union type

I have the following model:我有以下 model:

export interface IModel<T> {
 exp: number,
 value: T
}

I want to create a custom RxJS operator such as:我想创建一个自定义 RxJS 运算符,例如:

private customOperator<U extends A | B, T extends IModel<U>>(custom: Observable<T>): Observable<U> {
    return custom.pipe(map((x: T) => x.value ));
  }

But I Have a type error when using it:但是我在使用它时出现类型错误:

  mySub:  = new Subject<IModel<A>>;
  myObs$: Observable<A> = this.mySub.asObservable().pipe(this.customOperator); // <== ERROR

The error: Can't assign type 'Observable<A |错误:无法分配类型 'Observable<A | B>' to type 'Observable< A>'. B>' 来输入'Observable<A>'。

Any idea on how I could change my custom operator to avoid the issue?关于如何更改自定义运算符以避免该问题的任何想法?

Wrap the operator in a factory function.将操作员包裹在工厂 function 中。

private customOperator<T extends IModel<U>, U extends A | B> () {
  return (custom: Observable<T>): Observable<U> =>
   custom.pipe(map((x: T) => x.value ));
}

And then in the pipe use the operator as a function call instead of the function ref.然后在 pipe 中使用运算符作为 function 调用而不是 function 参考。

myObs$: Observable<A> = this.mySub.asObservable().pipe(this.customOperator());

cheers干杯

You need to use the Typescript type assertion feature.您需要使用 Typescript 类型断言功能。

In your case the compiler complains because myObs$ must be of type Observable<A> while your custom operator can return either an Observable<A> or an Observable<B> .在您的情况下,编译器会抱怨,因为myObs$必须Observable<A>类型而您的自定义运算符可以返回Observable<A>Observable<B>

So if you want to avoid the error you need to reassure Typescript that your custom operator will certainly return an Observable<A> .因此,如果您想避免错误,您需要向 Typescript 保证您的自定义运算符肯定会返回Observable<A> This is a trick to avoid a legitimate check of the Typescript compiler, so you better be sure you are doing the right thing.这是避免对 Typescript 编译器进行合法检查的技巧,因此您最好确保您做的是正确的事情。

So the code should look like this所以代码应该是这样的

myObs$: Observable<A> = this.mySub.asObservable().pipe(this.customOperator) as Observable<A>;

or, more simply或者,更简单地说

myObs$ = this.mySub.asObservable().pipe(this.customOperator) as Observable<A>;

If you hover over myObs$ , for instance within VSCode, you will see that the type inferred for myObs$ is actually Observable<A> even if you have not specified the type (at least in this last version of the code)如果您在myObs$上使用 hover,例如在 VSCode 中,您将看到为myObs$推断的类型实际上是Observable<A>即使您没有指定类型(至少在代码的最后一个版本中)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM