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

Typescript chooses wrong overload for RxJs's reduce call #22083

Closed
WiseBird opened this issue Feb 21, 2018 · 1 comment
Closed

Typescript chooses wrong overload for RxJs's reduce call #22083

WiseBird opened this issue Feb 21, 2018 · 1 comment

Comments

@WiseBird
Copy link

TypeScript Version: typescript@2.8.0-dev.20180221

Search Terms:
rxjs reduce overload

Code

import {Observable} from 'rxjs';

(null as Observable<{attribute: string, values: string[]}>)
    .reduce((acc, val) => ({
        ...acc,
        [val.attribute]: val.values,
    }), {});

Go to definition leads to

export declare function reduce<T>(this: Observable<T>, accumulator: (acc: T, value: T, index: number) => T, seed?: T): Observable<T>;

Expected behavior:
No errors

Actual behavior:

Error:(12, 14) TS2339: Property 'attribute' does not exist on type '{}'.
Error:(12, 30) TS2339: Property 'values' does not exist on type '{}'.

Reproduction: https://github.com/WiseBird/ts_rxjs_reduce

More info
I also try letable operators with the same effect:

import {Observable} from 'rxjs/Rx';
import {reduce} from 'rxjs/operators';

(null as Observable<{attribute: string, values: string[]}>)
    .let(
        reduce((acc, val) => ({
            ...acc,
            [val.attribute]: val.values,
        }), {}),
    );

Apparently ts chooses wrong overload and uses seed's type for value's type.

With simplified typings ts works OK:

interface Observable<T> {
    reduce(accumulator: (acc: T[], value: T) => T[], seed: T[]): Observable<T[]>;
    reduce(accumulator: (acc: T, value: T) => T, seed?: T): Observable<T>;
    reduce<R>(accumulator: (acc: R, value: T) => R, seed: R): Observable<R>;
}

(null as Observable<{attribute: string, values: string[]}>)
    .reduce((acc, val) => ({
        ...acc,
        [val.attribute]: val.values,
    }), {});

Go to declaration leads to

reduce<R>(accumulator: (acc: R, value: T) => R, seed: R): Observable<R>;
@aluanhaddad
Copy link
Contributor

aluanhaddad commented Feb 22, 2018

Getting the types right for this method has been a pain. It's not really a typescript issue. You can read about it starting with this issue and then follow the thread of referenced tissues and PRS ReactiveX/rxjs#2338

@microsoft microsoft locked and limited conversation to collaborators Jul 3, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants