diff --git a/spec/operators/multicast-spec.ts b/spec/operators/multicast-spec.ts index ca56dc38d3..cdcfd2d739 100644 --- a/spec/operators/multicast-spec.ts +++ b/spec/operators/multicast-spec.ts @@ -644,7 +644,7 @@ describe('Observable.prototype.multicast', () => { type('should infer the type', () => { /* tslint:disable:no-unused-variable */ const source = Rx.Observable.of(1, 2, 3); - const result: Rx.Observable = source.multicast(() => new Subject()); + const result: Rx.ConnectableObservable = source.multicast(() => new Subject()); /* tslint:enable:no-unused-variable */ }); @@ -661,5 +661,27 @@ describe('Observable.prototype.multicast', () => { const result: Rx.Observable = source.multicast(() => new Subject(), s => s.map(x => x + '!')); /* tslint:enable:no-unused-variable */ }); + + type('should infer the type for the pipeable operator', () => { + /* tslint:disable:no-unused-variable */ + const source = Rx.Observable.of(1, 2, 3); + // TODO: https://github.com/ReactiveX/rxjs/issues/2972 + const result: Rx.ConnectableObservable = Rx.operators.multicast(() => new Subject())(source); + /* tslint:enable:no-unused-variable */ + }); + + type('should infer the type for the pipeable operator with a selector', () => { + /* tslint:disable:no-unused-variable */ + const source = Rx.Observable.of(1, 2, 3); + const result: Rx.Observable = source.pipe(Rx.operators.multicast(() => new Subject(), s => s.map(x => x))); + /* tslint:enable:no-unused-variable */ + }); + + type('should infer the type for the pipeable operator with a type-changing selector', () => { + /* tslint:disable:no-unused-variable */ + const source = Rx.Observable.of(1, 2, 3); + const result: Rx.Observable = source.pipe(Rx.operators.multicast(() => new Subject(), s => s.map(x => x + '!'))); + /* tslint:enable:no-unused-variable */ + }); }); }); diff --git a/spec/operators/publish-spec.ts b/spec/operators/publish-spec.ts index b202502cef..075d769651 100644 --- a/spec/operators/publish-spec.ts +++ b/spec/operators/publish-spec.ts @@ -337,7 +337,7 @@ describe('Observable.prototype.publish', () => { type('should infer the type', () => { /* tslint:disable:no-unused-variable */ const source = Rx.Observable.of(1, 2, 3); - const result: Rx.Observable = source.publish(); + const result: Rx.ConnectableObservable = source.publish(); /* tslint:enable:no-unused-variable */ }); @@ -354,4 +354,26 @@ describe('Observable.prototype.publish', () => { const result: Rx.Observable = source.publish(s => s.map(x => x + '!')); /* tslint:enable:no-unused-variable */ }); + + type('should infer the type for the pipeable operator', () => { + /* tslint:disable:no-unused-variable */ + const source = Rx.Observable.of(1, 2, 3); + // TODO: https://github.com/ReactiveX/rxjs/issues/2972 + const result: Rx.ConnectableObservable = Rx.operators.publish()(source); + /* tslint:enable:no-unused-variable */ + }); + + type('should infer the type for the pipeable operator with a selector', () => { + /* tslint:disable:no-unused-variable */ + const source = Rx.Observable.of(1, 2, 3); + const result: Rx.Observable = source.pipe(Rx.operators.publish(s => s.map(x => x))); + /* tslint:enable:no-unused-variable */ + }); + + type('should infer the type for the pipeable operator with a type-changing selector', () => { + /* tslint:disable:no-unused-variable */ + const source = Rx.Observable.of(1, 2, 3); + const result: Rx.Observable = source.pipe(Rx.operators.publish(s => s.map(x => x + '!'))); + /* tslint:enable:no-unused-variable */ + }); }); diff --git a/spec/operators/publishBehavior-spec.ts b/spec/operators/publishBehavior-spec.ts index 6b91433cad..4f6337e8d5 100644 --- a/spec/operators/publishBehavior-spec.ts +++ b/spec/operators/publishBehavior-spec.ts @@ -3,6 +3,7 @@ import * as Rx from '../../dist/package/Rx'; import marbleTestingSignature = require('../helpers/marble-testing'); // tslint:disable-line:no-require-imports declare const { asDiagram }; +declare const type; declare const hot: typeof marbleTestingSignature.hot; declare const cold: typeof marbleTestingSignature.cold; declare const expectObservable: typeof marbleTestingSignature.expectObservable; @@ -336,4 +337,19 @@ describe('Observable.prototype.publishBehavior', () => { expect(results).to.deep.equal([]); done(); }); + + type('should infer the type', () => { + /* tslint:disable:no-unused-variable */ + const source = Rx.Observable.of(1, 2, 3); + const result: Rx.ConnectableObservable = source.publishBehavior(0); + /* tslint:enable:no-unused-variable */ + }); + + type('should infer the type for the pipeable operator', () => { + /* tslint:disable:no-unused-variable */ + const source = Rx.Observable.of(1, 2, 3); + // TODO: https://github.com/ReactiveX/rxjs/issues/2972 + const result: Rx.ConnectableObservable = Rx.operators.publishBehavior(0)(source); + /* tslint:enable:no-unused-variable */ + }); }); diff --git a/spec/operators/publishLast-spec.ts b/spec/operators/publishLast-spec.ts index b623493a38..8c03d3b2f9 100644 --- a/spec/operators/publishLast-spec.ts +++ b/spec/operators/publishLast-spec.ts @@ -3,6 +3,7 @@ import * as Rx from '../../dist/package/Rx'; import marbleTestingSignature = require('../helpers/marble-testing'); // tslint:disable-line:no-require-imports declare const { asDiagram }; +declare const type; declare const hot: typeof marbleTestingSignature.hot; declare const cold: typeof marbleTestingSignature.cold; declare const expectObservable: typeof marbleTestingSignature.expectObservable; @@ -257,4 +258,19 @@ describe('Observable.prototype.publishLast', () => { expect(subscriptions).to.equal(1); done(); }); + + type('should infer the type', () => { + /* tslint:disable:no-unused-variable */ + const source = Rx.Observable.of(1, 2, 3); + const result: Rx.ConnectableObservable = source.publishLast(); + /* tslint:enable:no-unused-variable */ + }); + + type('should infer the type for the pipeable operator', () => { + /* tslint:disable:no-unused-variable */ + const source = Rx.Observable.of(1, 2, 3); + // TODO: https://github.com/ReactiveX/rxjs/issues/2972 + const result: Rx.ConnectableObservable = Rx.operators.publishLast()(source); + /* tslint:enable:no-unused-variable */ + }); }); diff --git a/spec/operators/publishReplay-spec.ts b/spec/operators/publishReplay-spec.ts index dc6a0a937d..5b6c9ace8a 100644 --- a/spec/operators/publishReplay-spec.ts +++ b/spec/operators/publishReplay-spec.ts @@ -3,6 +3,7 @@ import * as Rx from '../../dist/package/Rx'; import marbleTestingSignature = require('../helpers/marble-testing'); // tslint:disable-line:no-require-imports declare const { asDiagram }; +declare const type; declare const hot: typeof marbleTestingSignature.hot; declare const cold: typeof marbleTestingSignature.cold; declare const expectObservable: typeof marbleTestingSignature.expectObservable; @@ -480,4 +481,47 @@ describe('Observable.prototype.publishReplay', () => { expectObservable(published).toBe(expected, undefined, error); expectSubscriptions(source.subscriptions).toBe(sourceSubs); }); + + type('should infer the type', () => { + /* tslint:disable:no-unused-variable */ + const source = Rx.Observable.of(1, 2, 3); + const result: Rx.ConnectableObservable = source.publishReplay(1); + /* tslint:enable:no-unused-variable */ + }); + + type('should infer the type with a selector', () => { + /* tslint:disable:no-unused-variable */ + const source = Rx.Observable.of(1, 2, 3); + const result: Rx.Observable = source.publishReplay(1, undefined, s => s.map(x => x)); + /* tslint:enable:no-unused-variable */ + }); + + type('should infer the type with a type-changing selector', () => { + /* tslint:disable:no-unused-variable */ + const source = Rx.Observable.of(1, 2, 3); + const result: Rx.Observable = source.publishReplay(1, undefined, s => s.map(x => x + '!')); + /* tslint:enable:no-unused-variable */ + }); + + type('should infer the type for the pipeable operator', () => { + /* tslint:disable:no-unused-variable */ + const source = Rx.Observable.of(1, 2, 3); + // TODO: https://github.com/ReactiveX/rxjs/issues/2972 + const result: Rx.ConnectableObservable = Rx.operators.publishReplay(1)(source); + /* tslint:enable:no-unused-variable */ + }); + + type('should infer the type for the pipeable operator with a selector', () => { + /* tslint:disable:no-unused-variable */ + const source = Rx.Observable.of(1, 2, 3); + const result: Rx.Observable = source.pipe(Rx.operators.publishReplay(1, undefined, s => s.map(x => x))); + /* tslint:enable:no-unused-variable */ + }); + + type('should infer the type for the pipeable operator with a type-changing selector', () => { + /* tslint:disable:no-unused-variable */ + const source = Rx.Observable.of(1, 2, 3); + const result: Rx.Observable = source.pipe(Rx.operators.publishReplay(1, undefined, s => s.map(x => x + '!'))); + /* tslint:enable:no-unused-variable */ + }); }); diff --git a/src/operators/multicast.ts b/src/operators/multicast.ts index 66effbcdd4..24d652c246 100644 --- a/src/operators/multicast.ts +++ b/src/operators/multicast.ts @@ -3,10 +3,10 @@ import { Operator } from '../Operator'; import { Subscriber } from '../Subscriber'; import { Observable } from '../Observable'; import { ConnectableObservable, connectableObservableDescriptor } from '../observable/ConnectableObservable'; -import { FactoryOrValue, MonoTypeOperatorFunction, OperatorFunction } from '../interfaces'; +import { FactoryOrValue, MonoTypeOperatorFunction, OperatorFunction, UnaryFunction } from '../interfaces'; /* tslint:disable:max-line-length */ -export function multicast(subjectOrSubjectFactory: FactoryOrValue>): MonoTypeOperatorFunction; +export function multicast(subjectOrSubjectFactory: FactoryOrValue>): UnaryFunction, ConnectableObservable>; export function multicast(SubjectFactory: (this: Observable) => Subject, selector?: MonoTypeOperatorFunction): MonoTypeOperatorFunction; export function multicast(SubjectFactory: (this: Observable) => Subject, selector?: OperatorFunction): OperatorFunction; /* tslint:enable:max-line-length */ diff --git a/src/operators/publish.ts b/src/operators/publish.ts index 7866156b3c..de813149e7 100644 --- a/src/operators/publish.ts +++ b/src/operators/publish.ts @@ -1,9 +1,11 @@ +import { Observable } from '../Observable'; import { Subject } from '../Subject'; import { multicast } from './multicast'; -import { MonoTypeOperatorFunction, OperatorFunction } from '../interfaces'; +import { ConnectableObservable } from '../observable/ConnectableObservable'; +import { MonoTypeOperatorFunction, OperatorFunction, UnaryFunction } from '../interfaces'; /* tslint:disable:max-line-length */ -export function publish(): MonoTypeOperatorFunction; +export function publish(): UnaryFunction, ConnectableObservable>; export function publish(selector: MonoTypeOperatorFunction): MonoTypeOperatorFunction; export function publish(selector: OperatorFunction): OperatorFunction; /* tslint:enable:max-line-length */ diff --git a/src/operators/publishLast.ts b/src/operators/publishLast.ts index 1ae01f4dcc..e20ebe051c 100644 --- a/src/operators/publishLast.ts +++ b/src/operators/publishLast.ts @@ -1,9 +1,9 @@ import { Observable } from '../Observable'; import { AsyncSubject } from '../AsyncSubject'; import { multicast } from './multicast'; -import { OperatorFunction } from '../interfaces'; +import { ConnectableObservable } from '../observable/ConnectableObservable'; +import { UnaryFunction } from '../interfaces'; -//TODO(benlesh): specify that the second type is actually a ConnectableObservable -export function publishLast(): OperatorFunction { +export function publishLast(): UnaryFunction, ConnectableObservable> { return (source: Observable) => multicast(new AsyncSubject())(source); }