From e678e81ba80f5bcc27b0e956295ce2fc8dfe4576 Mon Sep 17 00:00:00 2001 From: Ben Lesh Date: Sun, 17 May 2020 14:42:39 -0500 Subject: [PATCH] fix(Subject): no default generic --- spec-dtslint/AsyncSubject-spec.ts | 42 ++++++++++++++++++++ spec-dtslint/BehaviorSubject-spec.ts | 40 +++++++++++++++++++ spec-dtslint/ReplaySubject-spec.ts | 42 ++++++++++++++++++++ spec-dtslint/Subject-spec.ts | 42 ++++++++++++++++++++ spec/Subject-spec.ts | 3 +- spec/observables/dom/animationFrames-spec.ts | 2 +- spec/operators/take-spec.ts | 2 +- src/internal/Subject.ts | 11 ++--- 8 files changed, 173 insertions(+), 11 deletions(-) create mode 100644 spec-dtslint/AsyncSubject-spec.ts create mode 100644 spec-dtslint/BehaviorSubject-spec.ts create mode 100644 spec-dtslint/ReplaySubject-spec.ts create mode 100644 spec-dtslint/Subject-spec.ts diff --git a/spec-dtslint/AsyncSubject-spec.ts b/spec-dtslint/AsyncSubject-spec.ts new file mode 100644 index 0000000000..c79c40397e --- /dev/null +++ b/spec-dtslint/AsyncSubject-spec.ts @@ -0,0 +1,42 @@ +import { AsyncSubject } from 'rxjs'; + +describe('AsyncSubject', () => { + it('should handle no generic appropriately', () => { + const s1 = new AsyncSubject(); // $ExpectType AsyncSubject + s1.next(); // $ExpectError + s1.next('test'); // $ExpectType void + s1.subscribe(value => { + const x = value; // $ExpectType unknown + }); + }); + + it('should handle a generic of string appropriately', () => { + const s1 = new AsyncSubject(); // $ExpectType AsyncSubject + s1.next(); // $ExpectError + s1.next('test'); // $ExpectType void + s1.next(32); // $ExpectError + s1.subscribe(value => { + const x = value; // $ExpectType string + }); + }); + + it('should handle a generic of void appropriately', () => { + const s1 = new AsyncSubject(); // $ExpectType AsyncSubject + s1.next(); // $ExpectType void + s1.next(undefined); // $ExpectType void + s1.next('test'); // $ExpectError + s1.subscribe(value => { + const x = value; // $ExpectType void + }); + }); + + describe('asObservable', () => { + it('should return an observable of the same generic type', () => { + const s1 = new AsyncSubject(); + const o1 = s1.asObservable(); // $ExpectType Observable + + const s2 = new AsyncSubject(); + const o2 = s2.asObservable(); // $ExpectType Observable + }); + }); +}); \ No newline at end of file diff --git a/spec-dtslint/BehaviorSubject-spec.ts b/spec-dtslint/BehaviorSubject-spec.ts new file mode 100644 index 0000000000..fdc2b35a08 --- /dev/null +++ b/spec-dtslint/BehaviorSubject-spec.ts @@ -0,0 +1,40 @@ +import { BehaviorSubject } from 'rxjs'; + +describe('BehaviorSubject', () => { + it('should handle no generic appropriately', () => { + const s1 = new BehaviorSubject(); // $ExpectError + }); + + it('should handle an argument of string appropriately', () => { + const init = 'some string'; + const s1 = new BehaviorSubject(init); // $ExpectType BehaviorSubject + s1.next(); // $ExpectError + s1.next('test'); // $ExpectType void + s1.next(32); // $ExpectError + s1.subscribe(value => { + const x = value; // $ExpectType string + }); + const v = s1.getValue(); // $ExpectType string + }); + + it('should handle a generic of void appropriately', () => { + const s1 = new BehaviorSubject(undefined); // $ExpectType BehaviorSubject + s1.next(); // $ExpectType void + s1.next('test'); // $ExpectError + s1.next(32); // $ExpectError + s1.subscribe(value => { + const x = value; // $ExpectType void + }); + const v = s1.getValue(); // $ExpectType void + }); + + describe('asObservable', () => { + it('should return an observable of the same generic type', () => { + const s1 = new BehaviorSubject('test'); + const o1 = s1.asObservable(); // $ExpectType Observable + + const s2 = new BehaviorSubject(undefined); + const o2 = s2.asObservable(); // $ExpectType Observable + }); + }); +}); \ No newline at end of file diff --git a/spec-dtslint/ReplaySubject-spec.ts b/spec-dtslint/ReplaySubject-spec.ts new file mode 100644 index 0000000000..f9c9c30067 --- /dev/null +++ b/spec-dtslint/ReplaySubject-spec.ts @@ -0,0 +1,42 @@ +import { ReplaySubject } from 'rxjs'; + +describe('ReplaySubject', () => { + it('should handle no generic appropriately', () => { + const s1 = new ReplaySubject(); // $ExpectType ReplaySubject + s1.next(); // $ExpectError + s1.next('test'); // $ExpectType void + s1.subscribe(value => { + const x = value; // $ExpectType unknown + }); + }); + + it('should handle a generic of string appropriately', () => { + const s1 = new ReplaySubject(); // $ExpectType ReplaySubject + s1.next(); // $ExpectError + s1.next('test'); // $ExpectType void + s1.next(32); // $ExpectError + s1.subscribe(value => { + const x = value; // $ExpectType string + }); + }); + + it('should handle a generic of void appropriately', () => { + const s1 = new ReplaySubject(); // $ExpectType ReplaySubject + s1.next(); // $ExpectType void + s1.next(undefined); // $ExpectType void + s1.next('test'); // $ExpectError + s1.subscribe(value => { + const x = value; // $ExpectType void + }); + }); + + describe('asObservable', () => { + it('should return an observable of the same generic type', () => { + const s1 = new ReplaySubject(); + const o1 = s1.asObservable(); // $ExpectType Observable + + const s2 = new ReplaySubject(); + const o2 = s2.asObservable(); // $ExpectType Observable + }); + }); +}); \ No newline at end of file diff --git a/spec-dtslint/Subject-spec.ts b/spec-dtslint/Subject-spec.ts new file mode 100644 index 0000000000..1c21d8c84b --- /dev/null +++ b/spec-dtslint/Subject-spec.ts @@ -0,0 +1,42 @@ +import { Subject } from 'rxjs'; + +describe('Subject', () => { + it('should handle no generic appropriately', () => { + const s1 = new Subject(); // $ExpectType Subject + s1.next(); // $ExpectError + s1.next('test'); // $ExpectType void + s1.subscribe(value => { + const x = value; // $ExpectType unknown + }); + }); + + it('should handle a generic of string appropriately', () => { + const s1 = new Subject(); // $ExpectType Subject + s1.next(); // $ExpectError + s1.next('test'); // $ExpectType void + s1.next(32); // $ExpectError + s1.subscribe(value => { + const x = value; // $ExpectType string + }); + }); + + it('should handle a generic of void appropriately', () => { + const s1 = new Subject(); // $ExpectType Subject + s1.next(); // $ExpectType void + s1.next(undefined); // $ExpectType void + s1.next('test'); // $ExpectError + s1.subscribe(value => { + const x = value; // $ExpectType void + }); + }); + + describe('asObservable', () => { + it('should return an observable of the same generic type', () => { + const s1 = new Subject(); + const o1 = s1.asObservable(); // $ExpectType Observable + + const s2 = new Subject(); + const o2 = s2.asObservable(); // $ExpectType Observable + }); + }); +}); \ No newline at end of file diff --git a/spec/Subject-spec.ts b/spec/Subject-spec.ts index 3f234beafc..9f001a0906 100644 --- a/spec/Subject-spec.ts +++ b/spec/Subject-spec.ts @@ -7,14 +7,13 @@ import { delay } from 'rxjs/operators'; /** @test {Subject} */ describe('Subject', () => { - it('should allow next with empty, undefined or any when created with no type', (done: MochaDone) => { + it('should allow next with undefined or any when created with no type', (done: MochaDone) => { const subject = new Subject(); subject.subscribe(x => { expect(x).to.be.a('undefined'); }, null, done); const data: any = undefined; - subject.next(); subject.next(undefined); subject.next(data); subject.complete(); diff --git a/spec/observables/dom/animationFrames-spec.ts b/spec/observables/dom/animationFrames-spec.ts index afd6df5643..e61aec4cce 100644 --- a/spec/observables/dom/animationFrames-spec.ts +++ b/spec/observables/dom/animationFrames-spec.ts @@ -124,7 +124,7 @@ describe('animationFrame', () => { }); it('should compose with takeUntil', () => { - const subject = new Subject(); + const subject = new Subject(); const results: any[] = []; const source$ = animationFrames(); expect(requestAnimationFrame).not.to.have.been.called; diff --git a/spec/operators/take-spec.ts b/spec/operators/take-spec.ts index e18fdfa443..1b92c957e5 100644 --- a/spec/operators/take-spec.ts +++ b/spec/operators/take-spec.ts @@ -190,7 +190,7 @@ describe('take operator', () => { it('should complete when the source is reentrant', () => { let completed = false; - const source = new Subject(); + const source = new Subject(); source.pipe(take(5)).subscribe({ next() { source.next(); diff --git a/src/internal/Subject.ts b/src/internal/Subject.ts index bd8d7221b7..32399bd0e8 100644 --- a/src/internal/Subject.ts +++ b/src/internal/Subject.ts @@ -25,7 +25,7 @@ export class SubjectSubscriber extends Subscriber { * * @class Subject */ -export class Subject extends Observable implements SubscriptionLike { +export class Subject extends Observable implements SubscriptionLike { [rxSubscriberSymbol]() { return new SubjectSubscriber(this); @@ -41,13 +41,10 @@ export class Subject extends Observable implements SubscriptionLike thrownError: any = null; - constructor() { - super(); - } - - /**@nocollapse + /** + * @nocollapse * @deprecated use new Subject() instead - */ + */ static create: Function = (destination: Observer, source: Observable): AnonymousSubject => { return new AnonymousSubject(destination, source); }