From bd5ec2d710723dda64f75d2dae0f7b53244f8dfd Mon Sep 17 00:00:00 2001 From: Cotton Hou Date: Fri, 17 May 2019 00:50:08 +0800 Subject: [PATCH] fix(pluck): key union type strictness (#4585) --- compat/operator/pluck.ts | 1 + spec-dtslint/operators/pluck-spec.ts | 8 ++++---- spec/operators/pluck-spec.ts | 6 +++++- src/internal/operators/pluck.ts | 2 +- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/compat/operator/pluck.ts b/compat/operator/pluck.ts index c2a0d7b4d4..2e1b990743 100644 --- a/compat/operator/pluck.ts +++ b/compat/operator/pluck.ts @@ -28,5 +28,6 @@ import { pluck as higherOrder } from 'rxjs/operators'; * @owner Observable */ export function pluck(this: Observable, ...properties: string[]): Observable { + // @ts-ignore return higherOrder(...properties)(this) as Observable; } diff --git a/spec-dtslint/operators/pluck-spec.ts b/spec-dtslint/operators/pluck-spec.ts index 0690cf6bd6..573026e918 100644 --- a/spec-dtslint/operators/pluck-spec.ts +++ b/spec-dtslint/operators/pluck-spec.ts @@ -29,12 +29,12 @@ it('should support nested object of more than 6 layer depth', () => { const a = of({ a: { b: { c: { d: { e: { f: { name: 'abc' } } } } } } }).pipe(pluck('a', 'b', 'c', 'd', 'e', 'f', 'name')); // $ExpectType Observable<{}> }); -it('should infer empty interface for non-existance key', () => { - const a = of({ name: 'abc' }).pipe(pluck('xyz')); // $ExpectType Observable<{}> +it('should accept existing keys only', () => { + const a = of({ name: 'abc' }).pipe(pluck('xyz')); // $ExpectError }); -it('should infer empty interface for empty parameter', () => { - const a = of({ name: 'abc' }).pipe(pluck()); // $ExpectType Observable<{}> +it('should not accept empty parameter', () => { + const a = of({ name: 'abc' }).pipe(pluck()); // $ExpectError }); it('should accept string only', () => { diff --git a/spec/operators/pluck-spec.ts b/spec/operators/pluck-spec.ts index 2d710a9264..797b2f72ec 100644 --- a/spec/operators/pluck-spec.ts +++ b/spec/operators/pluck-spec.ts @@ -82,6 +82,7 @@ describe('pluck operator', () => { const expected = '--r-x--y-z---w-|'; const values: { [key: string]: number | undefined } = {r: 1, x: undefined, y: undefined, z: undefined, w: 5}; + // @ts-ignore const r = a.pipe(pluck('a', 'b', 'c')); expectObservable(r).toBe(expected, values); expectSubscriptions(a.subscriptions).toBe(asubs); @@ -89,6 +90,7 @@ describe('pluck operator', () => { it('should throw an error if not property is passed', () => { expect(() => { + // @ts-ignore of({prop: 1}, {prop: 2}).pipe(pluck()); }).to.throw(Error, 'list of properties cannot be empty.'); }); @@ -98,6 +100,7 @@ describe('pluck operator', () => { const asubs = '(^!)'; const expected = '#'; + // @ts-ignore const r = a.pipe(pluck('whatever')); expectObservable(r).toBe(expected); expectSubscriptions(a.subscriptions).toBe(asubs); @@ -120,6 +123,7 @@ describe('pluck operator', () => { const invoked = 0; const r = a.pipe( + // @ts-ignore pluck('whatever'), tap(null, null, () => { expect(invoked).to.equal(0); @@ -169,7 +173,7 @@ describe('pluck operator', () => { const r = a.pipe( mergeMap((x: { prop: string }) => of(x)), - pluck<{ prop: string }, string>('prop'), + pluck('prop'), mergeMap((x: string) => of(x)) ); diff --git a/src/internal/operators/pluck.ts b/src/internal/operators/pluck.ts index dbe050f25d..fd0d3eaeaf 100644 --- a/src/internal/operators/pluck.ts +++ b/src/internal/operators/pluck.ts @@ -9,7 +9,7 @@ export function pluck(k1: K1, k2: K2, k3: K3, k4: K4): OperatorFunction; export function pluck(k1: K1, k2: K2, k3: K3, k4: K4, k5: K5): OperatorFunction; export function pluck(k1: K1, k2: K2, k3: K3, k4: K4, k5: K5, k6: K6): OperatorFunction; -export function pluck(...properties: string[]): OperatorFunction; +export function pluck(k1: K1, k2: K2, k3: K3, k4: K4, k5: K5, k6: K6, ...rest: string[]): OperatorFunction; /* tslint:enable:max-line-length */ /**