简体   繁体   中英

RxJS Custom operator with typescript Union type

I have the following model:

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

I want to create a custom RxJS operator such as:

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 | B>' to type 'Observable< A>'.

Any idea on how I could change my custom operator to avoid the issue?

Wrap the operator in a factory 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.

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

cheers

You need to use the Typescript type assertion feature.

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> .

So if you want to avoid the error you need to reassure Typescript that your custom operator will certainly return an 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.

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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