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

feat(switchScan): add switchScan() operator #4442

Merged
merged 12 commits into from
Oct 5, 2020
Merged
2 changes: 2 additions & 0 deletions api_guard/dist/types/operators/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,8 @@ export declare function switchMapTo<R>(observable: ObservableInput<R>): Operator
export declare function switchMapTo<R>(observable: ObservableInput<R>, resultSelector: undefined): OperatorFunction<any, R>;
export declare function switchMapTo<T, I, R>(observable: ObservableInput<I>, resultSelector: (outerValue: T, innerValue: I, outerIndex: number, innerIndex: number) => R): OperatorFunction<T, R>;

export declare function switchScan<T, R, O extends ObservableInput<any>>(accumulator: (acc: R, value: T, index: number) => O, seed: R): OperatorFunction<T, ObservedValueOf<O>>;

export declare function take<T>(count: number): MonoTypeOperatorFunction<T>;

export declare function takeLast<T>(count: number): MonoTypeOperatorFunction<T>;
Expand Down
1 change: 1 addition & 0 deletions docs_app/content/guide/operators.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ These are Observable creation operators that also have join functionality -- emi
- [`partition`](/api/operators/partition)
- [`pluck`](/api/operators/pluck)
- [`scan`](/api/operators/scan)
- [`switchScan`](/api/operators/switchScan)
- [`switchMap`](/api/operators/switchMap)
- [`switchMapTo`](/api/operators/switchMapTo)
- [`window`](/api/operators/window)
Expand Down
3 changes: 3 additions & 0 deletions docs_app/tools/decision-tree-generator/src/tree.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@
- label: and output the computed values as a nested Observable when the source emits a value
children:
- label: mergeScan
- label: and output the computed values as a nested Observable when the source emits a value while unsubscribing from the previous nested Observable
children:
- label: switchScan
- label: I want to wrap its messages with metadata
children:
- label: that describes each notification (next, error, or complete)
Expand Down
38 changes: 38 additions & 0 deletions spec-dtslint/operators/switchScan-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { of } from 'rxjs';
import { switchScan } from 'rxjs/operators';

it('should infer correctly', () => {
const o = of(1, 2, 3).pipe(switchScan((acc: boolean, v: number) => of(Boolean(v)), false)); // $ExpectType Observable<boolean>
});

it('should infer correctly when using a single type', () => {
const o = of(1, 2, 3).pipe(switchScan((acc, v) => of(acc + v), 0)); // $ExpectType Observable<number>
martinsik marked this conversation as resolved.
Show resolved Hide resolved
});

it('should infer correctly when using seed of a different type', () => {
const o = of(1, 2, 3).pipe(switchScan((acc, v) => of(acc + v), '0')); // $ExpectType Observable<string>
});

it('should support a projector that takes an index', () => {
const o = of(1, 2, 3).pipe(switchScan((acc, v, index) => of(Boolean(v)), false)); // $ExpectType Observable<boolean>
});

it('should support projecting to union types', () => {
const o = of(Math.random()).pipe(switchScan(n => n > 0.5 ? of(123) : of('test'), 0)); // $ExpectType Observable<string | number>
});

it('should use the inferred accumulator return type over the seed type', () => {
const o = of(1, 2, 3).pipe(switchScan(p => of(1), [])); // $ExpectType Observable<number>
});

it('should enforce types', () => {
const o = of(1, 2, 3).pipe(switchScan()); // $ExpectError
});

it('should enforce the return type to be Observable', () => {
const o = of(1, 2, 3).pipe(switchScan(p => p)); // $ExpectError
});

it('should enforce seed and accumulator to have the same type', () => {
const o = of(1, 2, 3).pipe(switchScan((acc, p) => of([...acc, p]))); // $ExpectError
});
martinsik marked this conversation as resolved.
Show resolved Hide resolved
1 change: 1 addition & 0 deletions spec/operators/index-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ describe('operators/index', () => {
expect(index.skipWhile).to.exist;
expect(index.startWith).to.exist;
expect(index.switchAll).to.exist;
expect(index.switchScan).to.exist;
expect(index.switchMap).to.exist;
expect(index.switchMapTo).to.exist;
expect(index.take).to.exist;
Expand Down
Loading