I created a function that takes an object of subscribers, as seen below.
public subscribers = {
count: <EventEmitter<number>>new EventEmitter<number>(),
staticCount: <EventEmitter<number>>new EventEmitter<number>()
};
This function waits for both observables to complete, and returns an object with the keys of the object it received, as value the emitted value from the EventEmitter.
type AnyType<T> = {
[P in keyof T]: any;
}
function ZipObservable<T extends { [name: string]: EventEmitter<any>}>
(observables: T): Observable<AnyType<T>> {
const m = CreateMapFromObject(observables);
const o = new Subject<any>();
Observable.zip(...Array.from(m.values())).subscribe((res) => {
const keys = m.keys();
const c = res.reduce((r, v) => {
const k = <string>keys.next().value;
r[k] = v;
return r
}, {});
/**
*
*/
o.next(c);
o.complete();
});
return o.asObservable();
}
My current problem is at the type of the value set in the returned object. The object its keys are typed (as you can see in the image).
I also want the type of the value to be set to number (in this case).
I created a type; AnyType<T>
that's able to set the returned object its keys. Is it possible to also get it to set its value's type?
The type i want it to become, comes from the parameter, which receives a generic; EventEmitter<number>
.
Working type safety for the returned object.
So, you want ZipObservable
to return an object of type Observable<T>
, where the input parameter has the same keys as T
but the values for each key K
are EventEmitter<T[K]>
(where T[K]
is the type of the property value of the K
key of type T
). That is definitely achievable, through mapped types and inference from mapped types:
First let's define a mapped type which takes every property in T
and converts it to an EventEmitter<>
of the appropriate type:
type EventEmitters<T> = {
[K in keyof T]: EventEmitter<T[K]>
}
Now the ZipObservable
function signature can be written directly (I will leave the implementation up to you):
declare function ZipObservable<T>(eventEmitters: EventEmitters<T>): Observable<T>;
And it works because of inference from mapped types:
const ret = ZipObservable(subscribers).subscribe(r => r.count * 3); // no error
Hope that helps; good luck!!