From d78351983584483f4dc71234a6dbb9e1f5d72dcd Mon Sep 17 00:00:00 2001 From: JoostK Date: Mon, 16 Mar 2020 22:48:45 +0100 Subject: [PATCH] fix(common): let `KeyValuePipe` accept type unions with `null` (#36093) `KeyValuePipe` currently accepts `null` values as well as `Map`s and a few others. However, due to the way in which TS overloads work, a type of `T|null` will not be accepted by `KeyValuePipe`'s signatures, even though both `T` and `null` individually would be. To make this work, each signature that accepts some type `T` has been duplicated with a second one below it that accepts a `T|null` and includes `null` in its return type. Fixes #35743 PR Close #36093 --- goldens/public-api/common/common.d.ts | 7 +++++++ packages/common/src/pipes/keyvalue_pipe.ts | 11 +++++++++++ packages/common/test/pipes/keyvalue_pipe_spec.ts | 15 +++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/goldens/public-api/common/common.d.ts b/goldens/public-api/common/common.d.ts index 3cbe877311..c36711e0fd 100644 --- a/goldens/public-api/common/common.d.ts +++ b/goldens/public-api/common/common.d.ts @@ -139,10 +139,17 @@ export declare class KeyValuePipe implements PipeTransform { transform(input: { [key: string]: V; } | Map, compareFn?: (a: KeyValue, b: KeyValue) => number): Array>; + transform(input: { + [key: string]: V; + } | Map | null, compareFn?: (a: KeyValue, b: KeyValue) => number): Array> | null; transform(input: { [key: number]: V; } | Map, compareFn?: (a: KeyValue, b: KeyValue) => number): Array>; + transform(input: { + [key: number]: V; + } | Map | null, compareFn?: (a: KeyValue, b: KeyValue) => number): Array> | null; transform(input: Map, compareFn?: (a: KeyValue, b: KeyValue) => number): Array>; + transform(input: Map | null, compareFn?: (a: KeyValue, b: KeyValue) => number): Array> | null; } export declare class Location { diff --git a/packages/common/src/pipes/keyvalue_pipe.ts b/packages/common/src/pipes/keyvalue_pipe.ts index 5770f6a75b..592e57f958 100644 --- a/packages/common/src/pipes/keyvalue_pipe.ts +++ b/packages/common/src/pipes/keyvalue_pipe.ts @@ -55,12 +55,23 @@ export class KeyValuePipe implements PipeTransform { input: {[key: string]: V}|Map, compareFn?: (a: KeyValue, b: KeyValue) => number): Array>; + transform( + input: {[key: string]: V}|Map|null, + compareFn?: (a: KeyValue, b: KeyValue) => number): + Array>|null; transform( input: {[key: number]: V}|Map, compareFn?: (a: KeyValue, b: KeyValue) => number): Array>; + transform( + input: {[key: number]: V}|Map|null, + compareFn?: (a: KeyValue, b: KeyValue) => number): + Array>|null; transform(input: Map, compareFn?: (a: KeyValue, b: KeyValue) => number): Array>; + transform( + input: Map|null, + compareFn?: (a: KeyValue, b: KeyValue) => number): Array>|null; transform( input: null|{[key: string]: V, [key: number]: V}|Map, compareFn: (a: KeyValue, b: KeyValue) => number = defaultComparator): diff --git a/packages/common/test/pipes/keyvalue_pipe_spec.ts b/packages/common/test/pipes/keyvalue_pipe_spec.ts index 082fce6712..4433f9c98d 100644 --- a/packages/common/test/pipes/keyvalue_pipe_spec.ts +++ b/packages/common/test/pipes/keyvalue_pipe_spec.ts @@ -63,6 +63,16 @@ describe('KeyValuePipe', () => { const transform2 = pipe.transform({1: 3}); expect(transform1 !== transform2).toEqual(true); }); + it('should accept a type union of an object with string keys and null', () => { + let value !: {[key: string]: string} | null; + const pipe = new KeyValuePipe(defaultKeyValueDiffers); + expect(pipe.transform(value)).toEqual(null); + }); + it('should accept a type union of an object with number keys and null', () => { + let value !: {[key: number]: string} | null; + const pipe = new KeyValuePipe(defaultKeyValueDiffers); + expect(pipe.transform(value)).toEqual(null); + }); }); describe('Map', () => { @@ -115,6 +125,11 @@ describe('KeyValuePipe', () => { const transform2 = pipe.transform(new Map([[1, 3]])); expect(transform1 !== transform2).toEqual(true); }); + it('should accept a type union of a Map and null', () => { + let value !: Map| null; + const pipe = new KeyValuePipe(defaultKeyValueDiffers); + expect(pipe.transform(value)).toEqual(null); + }); }); });