Skip to content

Commit

Permalink
fix(typings): update withLatestFrom to conform to Operator type signa…
Browse files Browse the repository at this point in the history
…ture
  • Loading branch information
masaeedu committed Jan 20, 2016
1 parent 62f6983 commit 59c723e
Showing 1 changed file with 25 additions and 15 deletions.
40 changes: 25 additions & 15 deletions src/operator/withLatestFrom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import {tryCatch} from '../util/tryCatch';
import {errorObject} from '../util/errorObject';
import {OuterSubscriber} from '../OuterSubscriber';
import {subscribeToResult} from '../util/subscribeToResult';
import {isFunction} from '../util/isFunction';

export type Projection<U, R> = (...values: U[]) => R;

/**
* @param {Observable} observables the observables to get the latest values from.
Expand All @@ -24,32 +27,39 @@ import {subscribeToResult} from '../util/subscribeToResult';
* result: ---([a,d,x])---------([b,e,y])--------([c,f,z])---|
* ```
*/
export function withLatestFrom<T, R>(...args: Array<Observable<any> | ((...values: Array<any>) => R)>): Observable<R> {
let project: any;
if (typeof args[args.length - 1] === 'function') {
project = args.pop();
export function withLatestFrom<T, U, R>(...args: (Observable<U> | Projection<T | U, R>)[]): Observable<(T | U)[]> | Observable<R> {
let _this: Observable<T> = this;

let project: Projection<T | U, R>;
let observables: Observable<U>[];

let last = args[args.length - 1];
observables = <Observable<U>[]>args;
if (isFunction(last)) {
project = last;
args.pop();
}
const observables = <Observable<any>[]>args;
return this.lift(new WithLatestFromOperator(observables, project));
// TODO: The way this is implemented is not type safe. Need to fix implementation
return <any>_this.lift(new WithLatestFromOperator<T, U, R>(observables, project));

This comment has been minimized.

Copy link
@masaeedu

masaeedu Jan 20, 2016

Author Owner

The reason this isn't type safe is because we're propagating the optional project function into the operator, which changes the return type. If the project isn't present, we'll get (T | U)[]s out, if it is we'll get Rs out. As a result, lifting produces an Observable<(T | U)[] | R>, which is similar, but not assignable, to Observable<(T | U)[]> | Observable<R>. I couldn't see a way to fix this without a larger refactoring.

}

class WithLatestFromOperator<T, R> implements Operator<T, R> {
constructor(private observables: Observable<any>[],
private project?: (...values: any[]) => Observable<R>) {
class WithLatestFromOperator<T, U, R> implements Operator<T, (T | U)[] | R> {
constructor(private observables: Observable<U>[],
private project?: Projection<T | U, R>) {
}

call(subscriber: Subscriber<T>): Subscriber<T> {
return new WithLatestFromSubscriber(subscriber, this.observables, this.project);
call(subscriber: Subscriber<(T | U)[] | R>): Subscriber<T> {
return new WithLatestFromSubscriber<T, U, R>(subscriber, this.observables, this.project);
}
}

class WithLatestFromSubscriber<T, R> extends OuterSubscriber<T, R> {
class WithLatestFromSubscriber<T, U, R> extends OuterSubscriber<T, R> {
private values: any[];
private toRespond: number[] = [];

constructor(destination: Subscriber<T>,
private observables: Observable<any>[],
private project?: (...values: any[]) => Observable<R>) {
constructor(destination: Subscriber<(T | U)[] | R>,
private observables: Observable<U>[],
private project?: Projection<T | U, R>) {
super(destination);
const len = observables.length;
this.values = new Array(len);
Expand Down

0 comments on commit 59c723e

Please sign in to comment.