Skip to content

Commit

Permalink
fix(never): Observable.never() Observable.empty() and .ignoreElements…
Browse files Browse the repository at this point in the history
…() now return Observable<never>

fixes ReactiveX#2640

BREAKING CHANGE: Previously, `Observable.never()` `Observable.empty()`
and the `.ignoreElements()` operator all returned `Observable<T>` which
was incorrect since they actually never emit anything. Now they all
return `Observable<never>` (`never` was added in TS 2.0 as a special
type)
  • Loading branch information
jayphelps committed Jun 22, 2017
1 parent 0506ea0 commit c817818
Show file tree
Hide file tree
Showing 16 changed files with 29 additions and 29 deletions.
2 changes: 1 addition & 1 deletion spec/observables/empty-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const Observable = Rx.Observable;
describe('Observable.empty', () => {
asDiagram('empty')('should create a cold observable with only complete', () => {
const expected = '|';
const e1 = Observable.empty();
const e1: Rx.Observable<never> = Observable.empty();
expectObservable(e1).toBe(expected);
});
});
2 changes: 1 addition & 1 deletion spec/observables/from-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ describe('Observable.from', () => {
type(() => {
/* tslint:disable:no-unused-variable */
let o1: Rx.Observable<number> = Observable.from(<number[]>[], Rx.Scheduler.asap);
let o2: Rx.Observable<{ a: string }> = Observable.from(Observable.empty<{ a: string }>());
let o2: Rx.Observable<never> = Observable.from(Observable.empty());
let o3: Rx.Observable<{ b: number }> = Observable.from(new Promise<{b: number}>(resolve => resolve()));
/* tslint:enable:no-unused-variable */
});
Expand Down
2 changes: 1 addition & 1 deletion spec/observables/never-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const Observable = Rx.Observable;
describe('Observable.never', () => {
asDiagram('never')('should create a cold observable that never emits', () => {
const expected = '-';
const e1 = Observable.never();
const e1: Rx.Observable<never> = Observable.never();
expectObservable(e1).toBe(expected);
});
});
4 changes: 2 additions & 2 deletions spec/operators/debounce-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ describe('Observable.prototype.debounce', () => {
const e1subs = '^ !';
const expected = '--------a-x-yz---bxy---z--c--x--y--z|';

function selectorFunction(x) { return Observable.empty<number>(); }
function selectorFunction(x) { return Observable.empty(); }

expectObservable(e1.debounce(selectorFunction)).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(e1subs);
Expand All @@ -305,7 +305,7 @@ describe('Observable.prototype.debounce', () => {
const e1subs = '^ !';
const expected = '------------------------------------(z|)';

function selectorFunction(x) { return Observable.never<number>(); }
function selectorFunction(x) { return Observable.never(); }

expectObservable(e1.debounce(selectorFunction)).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(e1subs);
Expand Down
6 changes: 3 additions & 3 deletions spec/operators/race-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ describe('Observable.prototype.race', () => {
it('should unsubscribe former observables if a latter one emits immediately', () => {
const onNext = sinon.spy();
const onUnsubscribe = sinon.spy();
const e1 = Observable.never<string>().finally(onUnsubscribe); // Should be unsubscribed
const e1 = Observable.never().finally(onUnsubscribe); // Should be unsubscribed
const e2 = Observable.of('b'); // Wins the race

e1.race(e2).subscribe(onNext);
Expand All @@ -203,8 +203,8 @@ describe('Observable.prototype.race', () => {
it('should unsubscribe from immediately emitting observable on unsubscription', () => {
const onNext = sinon.spy();
const onUnsubscribe = sinon.spy();
const e1 = Observable.never<string>().startWith('a').finally(onUnsubscribe); // Wins the race
const e2 = Observable.never<string>(); // Loses the race
const e1 = Observable.never().startWith('a').finally(onUnsubscribe); // Wins the race
const e2 = Observable.never(); // Loses the race

const subscription = e1.race(e2).subscribe(onNext);
expect(onNext.calledWithExactly('a')).to.be.true;
Expand Down
2 changes: 1 addition & 1 deletion src/Notification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export class Notification<T> {
case 'E':
return Observable.throw(this.error);
case 'C':
return Observable.empty<T>();
return Observable.empty();
}
throw new Error('unexpected notification kind value');
}
Expand Down
2 changes: 1 addition & 1 deletion src/observable/ArrayLikeObservable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export class ArrayLikeObservable<T> extends Observable<T> {
static create<T>(arrayLike: ArrayLike<T>, scheduler?: IScheduler): Observable<T> {
const length = arrayLike.length;
if (length === 0) {
return new EmptyObservable<T>();
return new EmptyObservable();
} else if (length === 1) {
return new ScalarObservable<T>(<any>arrayLike[0], scheduler);
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/observable/ArrayObservable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export class ArrayObservable<T> extends Observable<T> {
} else if (len === 1) {
return new ScalarObservable<T>(<any>array[0], scheduler);
} else {
return new EmptyObservable<T>(scheduler);
return new EmptyObservable(scheduler);
}
}

Expand Down
10 changes: 5 additions & 5 deletions src/observable/EmptyObservable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export interface DispatchArg<T> {
* @extends {Ignored}
* @hide true
*/
export class EmptyObservable<T> extends Observable<T> {
export class EmptyObservable extends Observable<never> {

/**
* Creates an Observable that emits no items to the Observer and immediately
Expand Down Expand Up @@ -57,11 +57,11 @@ export class EmptyObservable<T> extends Observable<T> {
* @name empty
* @owner Observable
*/
static create<T>(scheduler?: IScheduler): Observable<T> {
return new EmptyObservable<T>(scheduler);
static create(scheduler?: IScheduler): Observable<never> {
return new EmptyObservable(scheduler);
}

static dispatch<T>(arg: DispatchArg<T>) {
static dispatch(arg: DispatchArg<never>) {
const { subscriber } = arg;
subscriber.complete();
}
Expand All @@ -70,7 +70,7 @@ export class EmptyObservable<T> extends Observable<T> {
super();
}

protected _subscribe(subscriber: Subscriber<T>): TeardownLogic {
protected _subscribe(subscriber: Subscriber<never>): TeardownLogic {

const scheduler = this.scheduler;

Expand Down
4 changes: 2 additions & 2 deletions src/observable/ForkJoinObservable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export class ForkJoinObservable<T> extends Observable<T> {
Array<SubscribableOrPromise<any>> |
((...values: Array<any>) => any)>): Observable<T> {
if (sources === null || arguments.length === 0) {
return new EmptyObservable<T>();
return new EmptyObservable();
}

let resultSelector: (...values: Array<any>) => any = null;
Expand All @@ -65,7 +65,7 @@ export class ForkJoinObservable<T> extends Observable<T> {
}

if (sources.length === 0) {
return new EmptyObservable<T>();
return new EmptyObservable();
}

return new ForkJoinObservable(<Array<SubscribableOrPromise<any>>>sources, resultSelector);
Expand Down
8 changes: 4 additions & 4 deletions src/observable/NeverObservable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { noop } from '../util/noop';
* @extends {Ignored}
* @hide true
*/
export class NeverObservable<T> extends Observable<T> {
export class NeverObservable extends Observable<never> {
/**
* Creates an Observable that emits no items to the Observer.
*
Expand Down Expand Up @@ -39,15 +39,15 @@ export class NeverObservable<T> extends Observable<T> {
* @name never
* @owner Observable
*/
static create<T>() {
return new NeverObservable<T>();
static create() {
return new NeverObservable();
}

constructor() {
super();
}

protected _subscribe(subscriber: Subscriber<T>): void {
protected _subscribe(subscriber: Subscriber<never>): void {
noop();
}
}
6 changes: 3 additions & 3 deletions src/operator/ignoreElements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ import { noop } from '../util/noop';
* @method ignoreElements
* @owner Observable
*/
export function ignoreElements<T>(this: Observable<T>): Observable<T> {
export function ignoreElements<T>(this: Observable<T>): Observable<never> {
return this.lift(new IgnoreElementsOperator());
};

class IgnoreElementsOperator<T, R> implements Operator<T, R> {
call(subscriber: Subscriber<R>, source: any): any {
class IgnoreElementsOperator<T> implements Operator<T, never> {
call(subscriber: Subscriber<never>, source: any): any {
return source.subscribe(new IgnoreElementsSubscriber(subscriber));
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/operator/repeat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { TeardownLogic } from '../Subscription';
*/
export function repeat<T>(this: Observable<T>, count: number = -1): Observable<T> {
if (count === 0) {
return new EmptyObservable<T>();
return new EmptyObservable();
} else if (count < 0) {
return this.lift(new RepeatOperator(-1, this));
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/operator/startWith.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,6 @@ export function startWith<T>(this: Observable<T>, ...array: Array<T | IScheduler
} else if (len > 1) {
return concatStatic(new ArrayObservable<T>(<T[]>array, scheduler), <Observable<T>>this);
} else {
return concatStatic(new EmptyObservable<T>(scheduler), <Observable<T>>this);
return concatStatic(new EmptyObservable(scheduler), <Observable<T>>this);
}
}
2 changes: 1 addition & 1 deletion src/operator/take.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import { TeardownLogic } from '../Subscription';
*/
export function take<T>(this: Observable<T>, count: number): Observable<T> {
if (count === 0) {
return new EmptyObservable<T>();
return new EmptyObservable();
} else {
return this.lift(new TakeOperator(count));
}
Expand Down
2 changes: 1 addition & 1 deletion src/operator/takeLast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ import { TeardownLogic } from '../Subscription';
*/
export function takeLast<T>(this: Observable<T>, count: number): Observable<T> {
if (count === 0) {
return new EmptyObservable<T>();
return new EmptyObservable();
} else {
return this.lift(new TakeLastOperator(count));
}
Expand Down

0 comments on commit c817818

Please sign in to comment.