diff --git a/spec-dtslint/operators/expand-spec.ts b/spec-dtslint/operators/expand-spec.ts index edba34e0a0..18b34fbd11 100644 --- a/spec-dtslint/operators/expand-spec.ts +++ b/spec-dtslint/operators/expand-spec.ts @@ -1,51 +1,65 @@ -import { of, asyncScheduler } from 'rxjs'; -import { expand } from 'rxjs/operators'; - -it('should infer correctly', () => { - const o = of(1, 2, 3).pipe(expand(value => of(value))); // $ExpectType Observable - const p = of(1, 2, 3).pipe(expand(value => [value])); // $ExpectType Observable - const q = of(1, 2, 3).pipe(expand(value => Promise.resolve(value))); // $ExpectType Observable -}); - -it('should infer correctly with a different type as the source', () => { - const o = of(1, 2, 3).pipe(expand(value => of('foo'))); // $ExpectType Observable - const p = of(1, 2, 3).pipe(expand(value => ['foo'])); // $ExpectType Observable - const q = of(1, 2, 3).pipe(expand(value => Promise.resolve('foo'))); // $ExpectType Observable -}); - -it('should support a project function with index', () => { - const o = of(1, 2, 3).pipe(expand((value, index) => of(index))); // $ExpectType Observable -}); - -it('should support concurrent parameter', () => { - const o = of(1, 2, 3).pipe(expand(value => of(1), 47)); // $ExpectType Observable -}); - -it('should support a scheduler', () => { - const o = of(1, 2, 3).pipe(expand(value => of(1), 47, asyncScheduler)); // $ExpectType Observable -}); - -it('should enforce types', () => { - const o = of(1, 2, 3).pipe(expand()); // $ExpectError -}); - -it('should enforce project types', () => { - const o = of(1, 2, 3).pipe(expand((value: string, index) => of(1))); // $ExpectError - const p = of(1, 2, 3).pipe(expand((value, index: string) => of(1))); // $ExpectError -}); - -it('should enforce project return type', () => { - const o = of(1, 2, 3).pipe(expand(value => 1)); // $ExpectError -}); - -it('should enforce concurrent type', () => { - const o = of(1, 2, 3).pipe(expand(value => of(1), 'foo')); // $ExpectError -}); - -it('should enforce scheduler type', () => { - const o = of(1, 2, 3).pipe(expand(value => of(1), 47, 'foo')); // $ExpectError -}); - -it('should support union types', () => { - const o = of(1).pipe(expand(x => typeof x === 'string' ? of(123) : of('test'))); // $ExpectType Observable -}); +import { of, asyncScheduler } from 'rxjs'; +import { expand } from 'rxjs/operators'; + +it('should infer correctly', () => { + const o = of(1, 2, 3).pipe(expand(value => of(value))); // $ExpectType Observable + const p = of(1, 2, 3).pipe(expand(value => [value])); // $ExpectType Observable + const q = of(1, 2, 3).pipe(expand(value => Promise.resolve(value))); // $ExpectType Observable +}); + +it('should infer correctly specifying value argument type', () => { + const o = of(1).pipe(expand((value: number | string) => of(value.toString()))); // $ExpectType Observable +}); + +it('should infer correctly with specifying different input/output types', () => { + const o = of(1).pipe(expand((value) => of(value.toString()))); // $ExpectType Observable +}); + +it('should enforce project output type to be assignable with its generic', () => { + const o = of(1).pipe(expand((value) => of(value))); // $ExpectError +}); + +it('should enforce project input type to be assignable with upstream', () => { + const o = of(1).pipe(expand((value: string) => of(value))); // $ExpectError +}); + +it('should enforce project input/output types compatibility by default', () => { + const o = of(1).pipe(expand((value) => of(value.toString()))); // $ExpectError +}); + +it('should support a project function with index', () => { + const o = of(1, 2, 3).pipe(expand((value, index) => of(index))); // $ExpectType Observable +}); + +it('should support concurrent parameter', () => { + const o = of(1, 2, 3).pipe(expand(value => of(1), 47)); // $ExpectType Observable +}); + +it('should support a scheduler', () => { + const o = of(1, 2, 3).pipe(expand(value => of(1), 47, asyncScheduler)); // $ExpectType Observable +}); + +it('should enforce types', () => { + const o = of(1, 2, 3).pipe(expand()); // $ExpectError +}); + +it('should enforce project types', () => { + const o = of(1, 2, 3).pipe(expand((value: string, index) => of(1))); // $ExpectError + const p = of(1, 2, 3).pipe(expand((value, index: string) => of(1))); // $ExpectError +}); + +it('should enforce project return type', () => { + const o = of(1, 2, 3).pipe(expand(value => 1)); // $ExpectError +}); + +it('should enforce concurrent type', () => { + const o = of(1, 2, 3).pipe(expand(value => of(1), 'foo')); // $ExpectError +}); + +it('should enforce scheduler type', () => { + const o = of(1, 2, 3).pipe(expand(value => of(1), 47, 'foo')); // $ExpectError +}); + +it('should support union types', () => { + const o = of(1).pipe(expand(x => typeof x === 'string' ? of(123) : of('test'))); // $ExpectType Observable +}); diff --git a/spec/operators/expand-spec.ts b/spec/operators/expand-spec.ts index fa5b8bd6ce..2593457e67 100644 --- a/spec/operators/expand-spec.ts +++ b/spec/operators/expand-spec.ts @@ -511,7 +511,7 @@ describe('expand', () => { synchronousObservable .pipe( - expand(() => EMPTY), + expand((_) => EMPTY), take(3) ) .subscribe(() => { diff --git a/src/internal/operators/expand.ts b/src/internal/operators/expand.ts index 0b0e43d243..7f9ae8751f 100644 --- a/src/internal/operators/expand.ts +++ b/src/internal/operators/expand.ts @@ -1,23 +1,23 @@ -import { OperatorFunction, ObservableInput, ObservedValueOf, SchedulerLike } from '../types'; +import { ObservableInput, SchedulerLike, OperatorFunction } from '../types'; import { Observable } from '../Observable'; import { mergeInternals } from './mergeInternals'; /* tslint:disable:max-line-length */ -export function expand>( - project: (value: T, index: number) => O, +export function expand( + project: (value: I | O, index: number) => ObservableInput, concurrent?: number, scheduler?: SchedulerLike -): OperatorFunction>; +): OperatorFunction; /** * @deprecated The `scheduler` parameter will be removed in v8. If you need to schedule the inner subscription, * use `subscribeOn` within the projection function: `expand((value) => fn(value).pipe(subscribeOn(scheduler)))`. * Details: Details: https://rxjs.dev/deprecations/scheduler-argument */ -export function expand>( - project: (value: T, index: number) => O, +export function expand( + project: (value: I | O, index: number) => ObservableInput, concurrent: number | undefined, scheduler: SchedulerLike -): OperatorFunction>; +): OperatorFunction; /* tslint:enable:max-line-length */ /** @@ -70,11 +70,11 @@ export function expand>( * the output Observable and merging the results of the Observables obtained * from this transformation. */ -export function expand>( - project: (value: T, index: number) => O, +export function expand( + project: (value: I | O, index: number) => ObservableInput, concurrent = Infinity, scheduler?: SchedulerLike -): OperatorFunction> { +): OperatorFunction { concurrent = (concurrent || 0) < 1 ? Infinity : concurrent; return (source) => new Observable((subscriber) => @@ -83,8 +83,7 @@ export function expand>( source, subscriber, - // HACK: Cast because TypeScript seems to get confused here. - project as (value: T, index: number) => ObservableInput>, + project, concurrent, // onBeforeNext