Reputation: 65
Recently I had a need to take an Observer parameter in a function, and I was banging my head on my desk trying to figure out how to do this in Typescript. You might recall taking a delegate
parameter in C#; that's basically what I was trying to do here. This was part of a subscribe(observer: Observer<any>)
. The reason I was doing this is because I was trying to add an AOP type of bookend for subscriptions. That's not the important part.
Basically to get this to work, you have to add a |
character behind your function parameter, and it ends up like this:
(observer: Observer<any>
| ((value: any) => void)): void
My question basically is what does the bold part do in that function signature? I've scoured every resource I can think of but can't figure it out. Without the portion after the |
, I was getting this error:
Argument of type '(res: any) => void' is not assignable to parameter of type 'Observer'. Property 'next' is missing in type '(res: any) => void'.
Once I added the pipe character and portion after, I was able to subscribe without issue in the traditional observer way (using an arrow function), and I have also confirmed that all subscriptions work (which rules out the portion after the pipe being a default value). Any ideas would be appreciated, because I hate seeing something work but having no idea why!
Upvotes: 1
Views: 3549
Reputation: 2858
as @echonax said: it means OR as @Rob said its a Union Type
but I started writing this and I dont feel like throwing it away :), just because I'm slow. :)
1st you restricted yuor method to accept Observers
class SubscribeMe<T> {
observable: Observable<T>;
susbscribe(observer: Observer<T>){
return observable.susbscribe(observer);
}
}
then you tried to invoke it with an Action like signature where Action is like
type Action = <T>(t:T)=> void
by doing :
susbscribeMe = new SubscribeMe<any>();
susbscribeMe.susbscribe((x)=> console.log(x));
That doesn't match signature previously provided.
Then you added Action like signature to the method
class SubscribeMe<T> {
observabel: Observable<T>
susbscribe(observer: Observer<T>| (x)=> void ){
return observable.susbscribe(observer);
}
}
or...
class SubscribeMe<T> {
observabel: Observable<T>
susbscribe(observer: Observer<T>| Action<T>){
return observable.susbscribe(observer);
}
}
With that You told typescript you can call me with an Action Or With an Observer
... and finally this is all posible becasue Rx.Observable interface (rxjs/Observable.d.ts)
defines an overloaded signature for "subscribe" like the following
* subscribe(): Subscription;
* subscribe(observer: PartialObserver<T>): Subscription;
* subscribe(next?: (value: T) => void, error?: (error: any) => void, complete?: () => void): Subscription;
Which means you can subscribe with
but will always return a Subscription
ex:
import * as Rx from "rxjs";
export class SubscribeMe<T> {
private _events = new Rx.Subject<T>();
/**
* Hide the source of the observable
* */
get events(): Rx.Observable<T> { return this._events.asObservable(); }
/**
* Accept any signature accepted by Rx.Observabe INTERFACE (rxjs/Observable.d.ts)
* subscribe(): Subscription;
* subscribe(observer: PartialObserver<T>): Subscription;
* subscribe(next?: (value: T) => void, error?: (error: any) => void, complete?: () => void): Subscription;
*
* as in OR Action<Ievent> Or Observer<Ievent> Or Null/Nothing/Nada
*/
subscribe = (observer?: (e:T) => void | Rx.Observer<T>) => {
return this.events.subscribe(observer);
}
}
Upvotes: 4
Reputation: 40657
It means the observer
is of type Observer<any>
|(or)
((value: any) => void)
: A function whose input is any
value and output is void
.
Upvotes: 2