From 4ec4ff1d9c804ca72be954a73ee6c55498b2c4eb Mon Sep 17 00:00:00 2001 From: Cotton Hou Date: Tue, 7 Aug 2018 02:51:08 +0800 Subject: [PATCH] fix(distinctUntilKeyChanged): improved key typing with keyof T (#3988) * fix(distinctUntilKeyChanged): correct signatures * chore(distinctUntilKeyChanged): nail down key's typing with keyof T --- compat/operator/distinctUntilKeyChanged.ts | 9 +++++---- .../operators/distinctUntilKeyChanged-spec.ts | 20 +++++++++++++++++++ .../operators/distinctUntilKeyChanged-spec.ts | 8 ++++---- .../operators/distinctUntilKeyChanged.ts | 6 +++--- 4 files changed, 32 insertions(+), 11 deletions(-) create mode 100644 spec-dtslint/operators/distinctUntilKeyChanged-spec.ts diff --git a/compat/operator/distinctUntilKeyChanged.ts b/compat/operator/distinctUntilKeyChanged.ts index e29a374084..6e9da5554a 100644 --- a/compat/operator/distinctUntilKeyChanged.ts +++ b/compat/operator/distinctUntilKeyChanged.ts @@ -3,8 +3,8 @@ import { Observable } from 'rxjs'; import { distinctUntilKeyChanged as higherOrder } from 'rxjs/operators'; /* tslint:disable:max-line-length */ -export function distinctUntilKeyChanged(this: Observable, key: string): Observable; -export function distinctUntilKeyChanged(this: Observable, key: string, compare: (x: K, y: K) => boolean): Observable; +export function distinctUntilKeyChanged(this: Observable, key: keyof T): Observable; +export function distinctUntilKeyChanged(this: Observable, key: K, compare: (x: T[K], y: T[K]) => boolean): Observable; /* tslint:enable:max-line-length */ /** @@ -64,6 +64,7 @@ export function distinctUntilKeyChanged(this: Observable, key: string, * @method distinctUntilKeyChanged * @owner Observable */ -export function distinctUntilKeyChanged(this: Observable, key: string, compare?: (x: T, y: T) => boolean): Observable { - return higherOrder(key, compare)(this); +// tslint:disable-next-line:max-line-length +export function distinctUntilKeyChanged(this: Observable, key: K, compare?: (x: T[K], y: T[K]) => boolean): Observable { + return higherOrder(key, compare)(this); } diff --git a/spec-dtslint/operators/distinctUntilKeyChanged-spec.ts b/spec-dtslint/operators/distinctUntilKeyChanged-spec.ts new file mode 100644 index 0000000000..5c0ad78fcb --- /dev/null +++ b/spec-dtslint/operators/distinctUntilKeyChanged-spec.ts @@ -0,0 +1,20 @@ +import { of } from 'rxjs'; +import { distinctUntilKeyChanged } from 'rxjs/operators'; + +const sample = {name: 'foobar', num: 42}; + +it('should enforce key set', () => { + const o = of(sample).pipe(distinctUntilKeyChanged('something')); // $ExpectError +}); + +it('should enforce key set with compare', () => { + const o = of(sample).pipe(distinctUntilKeyChanged('something', () => true)); // $ExpectError +}); + +it("should enforce compare's type", () => { + const o = of(sample).pipe(distinctUntilKeyChanged('name', (a: number, b: number) => true)); // $ExpectError +}); + +it("should enforce key set and compare's type", () => { + const o = of(sample).pipe(distinctUntilKeyChanged('something', (a: number, b: number) => true)); // $ExpectError +}); diff --git a/spec/operators/distinctUntilKeyChanged-spec.ts b/spec/operators/distinctUntilKeyChanged-spec.ts index f34bc3eea9..10674d0c94 100644 --- a/spec/operators/distinctUntilKeyChanged-spec.ts +++ b/spec/operators/distinctUntilKeyChanged-spec.ts @@ -185,7 +185,7 @@ describe('distinctUntilKeyChanged operator', () => { const e1subs = '^ !'; const expected = '--a--------------|'; - expectObservable((e1).pipe(distinctUntilKeyChanged('val', () => true))).toBe(expected, values); + expectObservable(e1.pipe(distinctUntilKeyChanged('val', () => true))).toBe(expected, values); expectSubscriptions(e1.subscriptions).toBe(e1subs); }); @@ -195,7 +195,7 @@ describe('distinctUntilKeyChanged operator', () => { const e1subs = '^ !'; const expected = '--a--a--a--a--a--a--|'; - expectObservable((e1).pipe(distinctUntilKeyChanged('val', () => false))).toBe(expected, values); + expectObservable(e1.pipe(distinctUntilKeyChanged('val', () => false))).toBe(expected, values); expectSubscriptions(e1.subscriptions).toBe(e1subs); }); @@ -206,7 +206,7 @@ describe('distinctUntilKeyChanged operator', () => { const expected = '--a-----c-----e--|'; const selector = (x: number, y: number) => y % 2 === 0; - expectObservable((e1).pipe(distinctUntilKeyChanged('val', selector))).toBe(expected, values); + expectObservable(e1.pipe(distinctUntilKeyChanged('val', selector))).toBe(expected, values); expectSubscriptions(e1.subscriptions).toBe(e1subs); }); @@ -222,7 +222,7 @@ describe('distinctUntilKeyChanged operator', () => { return x === y; }; - expectObservable((e1).pipe(distinctUntilKeyChanged('val', selector))).toBe(expected, values); + expectObservable(e1.pipe(distinctUntilKeyChanged('val', selector))).toBe(expected, values); expectSubscriptions(e1.subscriptions).toBe(e1subs); }); }); diff --git a/src/internal/operators/distinctUntilKeyChanged.ts b/src/internal/operators/distinctUntilKeyChanged.ts index 3a8e4bf91f..9b2da55ca0 100644 --- a/src/internal/operators/distinctUntilKeyChanged.ts +++ b/src/internal/operators/distinctUntilKeyChanged.ts @@ -2,8 +2,8 @@ import { distinctUntilChanged } from './distinctUntilChanged'; import { MonoTypeOperatorFunction } from '../types'; /* tslint:disable:max-line-length */ -export function distinctUntilKeyChanged(key: string): MonoTypeOperatorFunction; -export function distinctUntilKeyChanged(key: string, compare: (x: K, y: K) => boolean): MonoTypeOperatorFunction; +export function distinctUntilKeyChanged(key: keyof T): MonoTypeOperatorFunction; +export function distinctUntilKeyChanged(key: K, compare: (x: T[K], y: T[K]) => boolean): MonoTypeOperatorFunction; /* tslint:enable:max-line-length */ /** @@ -70,6 +70,6 @@ export function distinctUntilKeyChanged(key: string, compare: (x: K, y: K) * @method distinctUntilKeyChanged * @owner Observable */ -export function distinctUntilKeyChanged(key: string, compare?: (x: T, y: T) => boolean): MonoTypeOperatorFunction { +export function distinctUntilKeyChanged(key: K, compare?: (x: T[K], y: T[K]) => boolean): MonoTypeOperatorFunction { return distinctUntilChanged((x: T, y: T) => compare ? compare(x[key], y[key]) : x[key] === y[key]); }