Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(reduce): fix overload ordering #2382

Merged
merged 4 commits into from
Apr 3, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 65 additions & 4 deletions spec/operators/reduce-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -301,24 +301,85 @@ describe('Observable.prototype.reduce', () => {
});

it('should accept T typed reducers', () => {
type(() => {
let a: Rx.Observable<{ a: number; b: string }>;
const reduced = a.reduce((acc, value) => {
value.a = acc.a;
value.b = acc.b;
return acc;
});

reduced.subscribe(r => {
r.a.toExponential();
r.b.toLowerCase();
});
});
});

it('should accept R typed reducers when R is assignable to T', () => {
type(() => {
let a: Rx.Observable<{ a?: number; b?: string }>;
a.reduce((acc, value) => {
const reduced = a.reduce((acc, value) => {
value.a = acc.a;
value.b = acc.b;
return acc;
}, {});

reduced.subscribe(r => {
r.a.toExponential();
r.b.toLowerCase();
});
});
});

it('should accept R typed reducers when R is not assignable to T', () => {
type(() => {
let a: Rx.Observable<{ a: number; b: string }>;
const seed = {
as: [1],
bs: ['a']
};
const reduced = a.reduce((acc, value) => {
acc.as.push(value.a);
acc.bs.push(value.b);
return acc;
}, seed);

reduced.subscribe(r => {
r.as[0].toExponential();
r.bs[0].toLowerCase();
});
});
});

it('should accept R typed reducers', () => {
it('should accept R typed reducers and reduce to type R', () => {
type(() => {
let a: Rx.Observable<{ a: number; b: string }>;
a.reduce<{ a?: number; b?: string }>((acc, value) => {
const reduced = a.reduce<{ a?: number; b?: string }>((acc, value) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is a separate test required for generic type argument inference of R?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe so. Failure to infer R as distinct from T and T[] was the original issue.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@aluanhaddad This test doesn't seem to be verifying correct inference, because it specifies the generic type arg explicitly. Probably for an inference test you'd repeat this without the explicit type argument, then try to assign reduced to a variable of the explicit type you expect to have been inferred.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad, just realized the "R is not assignable to T" test already covers inference. 👍

value.a = acc.a;
value.b = acc.b;
return acc;
}, {});

reduced.subscribe(r => {
r.a.toExponential();
r.b.toLowerCase();
});
});
});

it('should accept array of R typed reducers and reduce to array of R', () => {
type(() => {
let a: Rx.Observable<number>;
const reduced = a.reduce((acc, cur) => {
console.log(acc);
acc.push(cur.toString());
return acc;
}, [] as string[]);

reduced.subscribe(rs => {
rs[0].toLowerCase();
});
});
});
});
});
4 changes: 2 additions & 2 deletions src/operator/reduce.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import { Operator } from '../Operator';
import { Subscriber } from '../Subscriber';

/* tslint:disable:max-line-length */
export function reduce<T>(this: Observable<T>, accumulator: (acc: T[], value: T, index: number) => T[], seed: T[]): Observable<T[]>;
export function reduce<T>(this: Observable<T>, accumulator: (acc: T, value: T, index: number) => T, seed?: T): Observable<T>;
export function reduce<T>(this: Observable<T>, accumulator: (acc: T[], value: T, index: number) => T[], seed?: T[]): Observable<T[]>;
export function reduce<T, R>(this: Observable<T>, accumulator: (acc: R, value: T, index: number) => R, seed?: R): Observable<R>;
export function reduce<T, R>(this: Observable<T>, accumulator: (acc: R, value: T, index: number) => R, seed: R): Observable<R>;
/* tslint:enable:max-line-length */

/**
Expand Down