From 54574c8ad2a45ddadde18712245a9baee381a3d5 Mon Sep 17 00:00:00 2001 From: Brian Greig Date: Sat, 15 Oct 2022 14:23:17 -0400 Subject: [PATCH 01/26] style(eslint): apply specified code style changes Signed-off-by: Derek Lewis --- src/index.ts | 45 ++++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/src/index.ts b/src/index.ts index 641345b..ff2b006 100644 --- a/src/index.ts +++ b/src/index.ts @@ -32,11 +32,11 @@ const _hasOwn = Object.prototype.hasOwnProperty; * @template T */ export function map(opt_initial: T | undefined) { - const obj = Object.create(null); + const object = Object.create(null); if (opt_initial) { - Object.assign(obj, opt_initial); + Object.assign(object, opt_initial); } - return obj; + return object; } /** @@ -46,8 +46,8 @@ export function map(opt_initial: T | undefined) { * @returns {boolean} * @template T */ -export function hasOwn(obj: T, key: string) { - return _hasOwn.call(obj, key); +export function hasOwn(object: T, key: string) { + return _hasOwn.call(object, key); } /** @@ -57,12 +57,11 @@ export function hasOwn(obj: T, key: string) { * @param {string} key * @returns {unknown} */ -export function ownProperty(obj: Record, key: string) { - if (hasOwn(obj, key)) { - return obj[key]; - } else { - return undefined; - } +export function ownProperty( + object: Record, + key: string +) { + return hasOwn(object, key) ? object[key] : undefined; } interface ITargetSourceDepth { @@ -84,10 +83,10 @@ interface ITargetSourceDepth { */ export function deepMerge(target: Object, source: Object, depth = 10): Object { // Keep track of seen objects to detect recursive references. - const seen: Array = []; + const seen: Object[] = []; /** @type {!Array} */ - const queue: Array = []; + const queue: ITargetSourceDepth[] = []; queue.push({ t: target, s: source, d: 0 }); // BFS to ensure objects don't have recursive references at shallower depths. @@ -104,7 +103,7 @@ export function deepMerge(target: Object, source: Object, depth = 10): Object { Object.assign(t, s); continue; } - Object.keys(s).forEach((key) => { + for (const key of Object.keys(s)) { const newValue = s[key]; // Perform a deep merge IFF both target and source have the same key // whose corresponding values are objects. @@ -112,11 +111,11 @@ export function deepMerge(target: Object, source: Object, depth = 10): Object { const oldValue = t[key]; if (isObject(newValue) && isObject(oldValue)) { queue.push({ t: oldValue, s: newValue, d: d + 1 }); - return; + continue; } } t[key] = newValue; - }); + } } return target; } @@ -130,7 +129,7 @@ export function objectsEqualShallow( o1: Record | null | undefined, o2: Record | null | undefined ): boolean { - if (o1 == null || o2 == null) { + if (o1 == undefined || o2 == undefined) { // Null is only equal to null, and undefined to undefined. return o1 === o2; } @@ -160,14 +159,14 @@ export function objectsEqualShallow( * @template T,R */ export function memo( - obj: T, - prop: P, - factory: (arg0: T, arg1: P) => T[P] + object: T, + property: P, + factory: (argument0: T, argument1: P) => T[P] ): T[P] { - let result = obj[prop]; + let result = object[property]; if (result === undefined) { - result = factory(obj, prop); - obj[prop] = result; + result = factory(object, property); + object[property] = result; } return result; } From ebe562d130f3d306a86e9995d13c8fbcdff9e9fe Mon Sep 17 00:00:00 2001 From: Derek Lewis Date: Sun, 16 Oct 2022 08:55:56 -0400 Subject: [PATCH 02/26] fix(src): use object spread spread props don't trigger getters on the target object Refs: https://babeljs.io/docs/en/assumptions#setspreadproperties Co-authored-by: septs Signed-off-by: Derek Lewis --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index ff2b006..96d2815 100644 --- a/src/index.ts +++ b/src/index.ts @@ -36,7 +36,7 @@ export function map(opt_initial: T | undefined) { if (opt_initial) { Object.assign(object, opt_initial); } - return object; + return { ...opt_initial }; } /** From c33049e289b3c916fbcf4a74f35c86d88ae3b011 Mon Sep 17 00:00:00 2001 From: Derek Lewis Date: Sun, 16 Oct 2022 09:12:25 -0400 Subject: [PATCH 03/26] fix(src): use object literal instead of banned type Signed-off-by: Derek Lewis --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 96d2815..de674c4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -83,7 +83,7 @@ interface ITargetSourceDepth { */ export function deepMerge(target: Object, source: Object, depth = 10): Object { // Keep track of seen objects to detect recursive references. - const seen: Object[] = []; + const seen: Array<{}> = []; /** @type {!Array} */ const queue: ITargetSourceDepth[] = []; From c34389bbbec0e2e56c2673de94ce016111cbb477 Mon Sep 17 00:00:00 2001 From: Derek Lewis Date: Sun, 16 Oct 2022 09:38:30 -0400 Subject: [PATCH 04/26] style(index): prefer tailing commas for js objects Signed-off-by: Derek Lewis --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index de674c4..6f2267c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -161,7 +161,7 @@ export function objectsEqualShallow( export function memo( object: T, property: P, - factory: (argument0: T, argument1: P) => T[P] + factory: (argument0: T, argument1: P) => T[P], ): T[P] { let result = object[property]; if (result === undefined) { From 607e6c099ca4c8080f44e15c4ca48d453da61b4f Mon Sep 17 00:00:00 2001 From: Derek Lewis Date: Sun, 16 Oct 2022 09:40:56 -0400 Subject: [PATCH 05/26] fix(src): update to use trailing commans for js objects Signed-off-by: Derek Lewis --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 6f2267c..127887a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -59,7 +59,7 @@ export function hasOwn(object: T, key: string) { */ export function ownProperty( object: Record, - key: string + key: string, ) { return hasOwn(object, key) ? object[key] : undefined; } From 24ced7d9d4e29d27c1605fdeaeb8a0cde58b0bc4 Mon Sep 17 00:00:00 2001 From: Derek Lewis Date: Sun, 16 Oct 2022 12:55:41 -0400 Subject: [PATCH 06/26] fix Signed-off-by: Derek Lewis --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 127887a..919f9f0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -83,7 +83,7 @@ interface ITargetSourceDepth { */ export function deepMerge(target: Object, source: Object, depth = 10): Object { // Keep track of seen objects to detect recursive references. - const seen: Array<{}> = []; + const seen: object[] = []; /** @type {!Array} */ const queue: ITargetSourceDepth[] = []; From 3209b2a16f5d0cdbe1f6f8684776f151ef3e448f Mon Sep 17 00:00:00 2001 From: Derek Lewis Date: Sun, 16 Oct 2022 13:55:21 -0400 Subject: [PATCH 07/26] Update src/index.ts Signed-off-by: Derek Lewis --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 919f9f0..7651382 100644 --- a/src/index.ts +++ b/src/index.ts @@ -61,7 +61,7 @@ export function ownProperty( object: Record, key: string, ) { - return hasOwn(object, key) ? object[key] : undefined; + return hasOwn(object, key) ? Reflect.get(object, key) : undefined; } interface ITargetSourceDepth { From ffc58ba4db2f7745641f1a2c4181692b6a4b0b3b Mon Sep 17 00:00:00 2001 From: Derek Lewis Date: Sun, 16 Oct 2022 13:59:01 -0400 Subject: [PATCH 08/26] Update src/index.ts Signed-off-by: Derek Lewis --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 7651382..7747588 100644 --- a/src/index.ts +++ b/src/index.ts @@ -104,7 +104,7 @@ export function deepMerge(target: Object, source: Object, depth = 10): Object { continue; } for (const key of Object.keys(s)) { - const newValue = s[key]; + const newValue = Reflect.get(s, key); // Perform a deep merge IFF both target and source have the same key // whose corresponding values are objects. if (hasOwn(t, key)) { From 6da9d15a7ba69e1063bff69ddf961e72ed511328 Mon Sep 17 00:00:00 2001 From: Derek Lewis Date: Sun, 16 Oct 2022 14:05:13 -0400 Subject: [PATCH 09/26] Update src/index.ts Signed-off-by: Derek Lewis --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 7747588..7d41ced 100644 --- a/src/index.ts +++ b/src/index.ts @@ -163,7 +163,7 @@ export function memo( property: P, factory: (argument0: T, argument1: P) => T[P], ): T[P] { - let result = object[property]; + let result = Reflect.get(object, property); if (result === undefined) { result = factory(object, property); object[property] = result; From 96e08c39879d6a078ad95d7d8c2bfb6bfd52e16e Mon Sep 17 00:00:00 2001 From: Derek Lewis Date: Sun, 16 Oct 2022 14:05:51 -0400 Subject: [PATCH 10/26] Update src/index.ts Signed-off-by: Derek Lewis --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 7d41ced..879c860 100644 --- a/src/index.ts +++ b/src/index.ts @@ -108,7 +108,7 @@ export function deepMerge(target: Object, source: Object, depth = 10): Object { // Perform a deep merge IFF both target and source have the same key // whose corresponding values are objects. if (hasOwn(t, key)) { - const oldValue = t[key]; + const oldValue = Reflect.get(t, key); if (isObject(newValue) && isObject(oldValue)) { queue.push({ t: oldValue, s: newValue, d: d + 1 }); continue; From 8e963d19fcb30f590af67c0378bb83dfa24b5a12 Mon Sep 17 00:00:00 2001 From: Derek Lewis Date: Sun, 16 Oct 2022 14:06:23 -0400 Subject: [PATCH 11/26] Update src/index.ts Signed-off-by: Derek Lewis --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 879c860..fe84ad7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -114,7 +114,7 @@ export function deepMerge(target: Object, source: Object, depth = 10): Object { continue; } } - t[key] = newValue; + Reflect.set(t, key, newValue); } } return target; From fcb48a34d4d8a304a19f5ce2f17df7a79f2cc649 Mon Sep 17 00:00:00 2001 From: Derek Lewis Date: Sun, 16 Oct 2022 14:08:35 -0400 Subject: [PATCH 12/26] Update src/index.ts Signed-off-by: Derek Lewis --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index fe84ad7..bbcb9a1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -166,7 +166,7 @@ export function memo( let result = Reflect.get(object, property); if (result === undefined) { result = factory(object, property); - object[property] = result; + Reflect.set(object, property, result); } return result; } From 5dce04313c671664c7908d8f9b5e8d3fc73ee047 Mon Sep 17 00:00:00 2001 From: Derek Lewis Date: Sun, 16 Oct 2022 14:30:31 -0400 Subject: [PATCH 13/26] add note to return to later Signed-off-by: Derek Lewis --- src/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/index.ts b/src/index.ts index bbcb9a1..4016728 100644 --- a/src/index.ts +++ b/src/index.ts @@ -36,6 +36,8 @@ export function map(opt_initial: T | undefined) { if (opt_initial) { Object.assign(object, opt_initial); } + + // FIXME(@DerekNonGeneric): Should we be creating objects w/ null protos? return { ...opt_initial }; } From 79f5d80eff4e94a36d75b7d293e520de4ca50d9d Mon Sep 17 00:00:00 2001 From: Derek Lewis Date: Sun, 16 Oct 2022 19:56:05 -0400 Subject: [PATCH 14/26] Update src/index.ts Signed-off-by: Derek Lewis --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 4016728..add64b9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -31,7 +31,7 @@ const _hasOwn = Object.prototype.hasOwnProperty; * @returns {T} * @template T */ -export function map(opt_initial: T | undefined) { +export const map = (opt_initial: T | undefined) { const object = Object.create(null); if (opt_initial) { Object.assign(object, opt_initial); From e66a051761ec10ede1118399697c97c5757dce61 Mon Sep 17 00:00:00 2001 From: Derek Lewis Date: Sun, 16 Oct 2022 19:56:30 -0400 Subject: [PATCH 15/26] Update src/index.ts Signed-off-by: Derek Lewis --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index add64b9..9fbfd13 100644 --- a/src/index.ts +++ b/src/index.ts @@ -48,7 +48,7 @@ export const map = (opt_initial: T | undefined) { * @returns {boolean} * @template T */ -export function hasOwn(object: T, key: string) { +export const hasOwn = (object: T, key: string): boolean { return _hasOwn.call(object, key); } From 5c7205c50b47a5551d724d7e5cbf461a046d3ab2 Mon Sep 17 00:00:00 2001 From: Derek Lewis Date: Sun, 16 Oct 2022 19:56:49 -0400 Subject: [PATCH 16/26] Update src/index.ts Signed-off-by: Derek Lewis --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 9fbfd13..c6f51d7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -83,7 +83,7 @@ interface ITargetSourceDepth { * @throws {Error} If source contains a circular reference. * Note: Only nested objects are deep-merged, primitives and arrays are not. */ -export function deepMerge(target: Object, source: Object, depth = 10): Object { +export const deepMerge = (target: object, source: object, depth = 10): object { // Keep track of seen objects to detect recursive references. const seen: object[] = []; From 74f22dc5ce688424728cf0302f944e8b50d80729 Mon Sep 17 00:00:00 2001 From: Derek Lewis Date: Sun, 16 Oct 2022 20:01:23 -0400 Subject: [PATCH 17/26] Update src/index.ts Signed-off-by: Derek Lewis --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index c6f51d7..c41fbf9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -62,7 +62,7 @@ export const hasOwn = (object: T, key: string): boolean { export function ownProperty( object: Record, key: string, -) { +): unknown => { return hasOwn(object, key) ? Reflect.get(object, key) : undefined; } From d13b92521634c2dee61f1b6655cf56ca1a50b083 Mon Sep 17 00:00:00 2001 From: Derek Lewis Date: Sun, 16 Oct 2022 20:01:41 -0400 Subject: [PATCH 18/26] Update src/index.ts Signed-off-by: Derek Lewis --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index c41fbf9..b72fdbc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -160,7 +160,7 @@ export function objectsEqualShallow( * @returns {R} * @template T,R */ -export function memo( +export const memo = ( object: T, property: P, factory: (argument0: T, argument1: P) => T[P], From 4545791ad79d1300acdb9b8d04ac76b9faa1fd1d Mon Sep 17 00:00:00 2001 From: Derek Lewis Date: Sun, 16 Oct 2022 20:02:04 -0400 Subject: [PATCH 19/26] Update src/index.ts Signed-off-by: Derek Lewis --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index b72fdbc..4e8db83 100644 --- a/src/index.ts +++ b/src/index.ts @@ -59,7 +59,7 @@ export const hasOwn = (object: T, key: string): boolean { * @param {string} key * @returns {unknown} */ -export function ownProperty( +export const ownProperty = ( object: Record, key: string, ): unknown => { From 1b80afef5b9dbdbf0417f5c74dd96ca5b16cf262 Mon Sep 17 00:00:00 2001 From: Derek Lewis Date: Sun, 16 Oct 2022 20:02:53 -0400 Subject: [PATCH 20/26] Update src/index.ts Signed-off-by: Derek Lewis --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 4e8db83..0609ee1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -31,7 +31,7 @@ const _hasOwn = Object.prototype.hasOwnProperty; * @returns {T} * @template T */ -export const map = (opt_initial: T | undefined) { +export const map = (opt_initial: T | undefined): object => { const object = Object.create(null); if (opt_initial) { Object.assign(object, opt_initial); From a14acd2175ee63725ad15e9cb4219aeb4330aab4 Mon Sep 17 00:00:00 2001 From: Derek Lewis Date: Sun, 16 Oct 2022 20:03:36 -0400 Subject: [PATCH 21/26] Update src/index.ts Signed-off-by: Derek Lewis --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 0609ee1..8f51fe3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -164,7 +164,7 @@ export const memo = ( object: T, property: P, factory: (argument0: T, argument1: P) => T[P], -): T[P] { +): T[P] => { let result = Reflect.get(object, property); if (result === undefined) { result = factory(object, property); From 881139fff9a3eb58001b46b4963ed6e804c27f53 Mon Sep 17 00:00:00 2001 From: Derek Lewis Date: Sun, 16 Oct 2022 20:04:10 -0400 Subject: [PATCH 22/26] Update src/index.ts Signed-off-by: Derek Lewis --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 8f51fe3..bf79de9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -48,7 +48,7 @@ export const map = (opt_initial: T | undefined): object => { * @returns {boolean} * @template T */ -export const hasOwn = (object: T, key: string): boolean { +export const hasOwn = (object: T, key: string): boolean => { return _hasOwn.call(object, key); } From c2f601387a9a43069edd018d8b389d1ad67f633b Mon Sep 17 00:00:00 2001 From: Derek Lewis Date: Sun, 16 Oct 2022 20:06:48 -0400 Subject: [PATCH 23/26] Update src/index.ts Signed-off-by: Derek Lewis --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index bf79de9..9b13d31 100644 --- a/src/index.ts +++ b/src/index.ts @@ -83,7 +83,7 @@ interface ITargetSourceDepth { * @throws {Error} If source contains a circular reference. * Note: Only nested objects are deep-merged, primitives and arrays are not. */ -export const deepMerge = (target: object, source: object, depth = 10): object { +export const deepMerge = (target: object, source: object, depth = 10): object => { // Keep track of seen objects to detect recursive references. const seen: object[] = []; From c077e4f23369da2e43068fc25517447d477839dd Mon Sep 17 00:00:00 2001 From: Derek Lewis Date: Sun, 16 Oct 2022 20:07:57 -0400 Subject: [PATCH 24/26] Update src/index.ts Signed-off-by: Derek Lewis --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 9b13d31..5bc0bb2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -130,7 +130,7 @@ export const deepMerge = (target: object, source: object, depth = 10): object => export function objectsEqualShallow( o1: Record | null | undefined, o2: Record | null | undefined -): boolean { +): boolean => { if (o1 == undefined || o2 == undefined) { // Null is only equal to null, and undefined to undefined. return o1 === o2; From 934c84e4bf596506efe1b6579a80dd5538f08ed9 Mon Sep 17 00:00:00 2001 From: Derek Lewis Date: Sun, 16 Oct 2022 20:08:48 -0400 Subject: [PATCH 25/26] Update src/index.ts Signed-off-by: Derek Lewis --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 5bc0bb2..f8c9a3c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -127,7 +127,7 @@ export const deepMerge = (target: object, source: object, depth = 10): object => * @param {!Record | null | undefined} o2 * @returns {boolean} */ -export function objectsEqualShallow( +export const objectsEqualShallow = ( o1: Record | null | undefined, o2: Record | null | undefined ): boolean => { From 4fc93eeed6bad9afda60808fd69e9a394f18e9e0 Mon Sep 17 00:00:00 2001 From: Derek Lewis Date: Sun, 16 Oct 2022 22:17:16 -0400 Subject: [PATCH 26/26] fix(src): address remaining typecheck issues Signed-off-by: Derek Lewis --- src/index.ts | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/index.ts b/src/index.ts index f8c9a3c..25c592d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -31,7 +31,7 @@ const _hasOwn = Object.prototype.hasOwnProperty; * @returns {T} * @template T */ -export const map = (opt_initial: T | undefined): object => { +export const map = (opt_initial: T | null | undefined): object => { const object = Object.create(null); if (opt_initial) { Object.assign(object, opt_initial); @@ -66,34 +66,36 @@ export const ownProperty = ( return hasOwn(object, key) ? Reflect.get(object, key) : undefined; } -interface ITargetSourceDepth { - t: Object; - s: Object; +/** @typedef {{t: object, s: object, d: number}} DeepMergeTuple */ +type DeepMergeTuple = { + t: object; + s: object; d: number; } /** * Deep merges source into target. * - * @param {!Object} target - * @param {!Object} source - * @param {number} depth The maximum merge depth. If exceeded, Object.assign - * will be used instead. - * @returns {!Object} + * @param {!object} target + * @param {!object} source + * @param {!number} depth The maximum merge depth. If exceeded, `Object.assign` + * will be used instead. + * @return {!object} * @throws {Error} If source contains a circular reference. * Note: Only nested objects are deep-merged, primitives and arrays are not. */ export const deepMerge = (target: object, source: object, depth = 10): object => { // Keep track of seen objects to detect recursive references. + /** @type {!object[]} */ const seen: object[] = []; - /** @type {!Array} */ - const queue: ITargetSourceDepth[] = []; + /** @type {!DeepMergeTuple[]} */ + const queue: DeepMergeTuple[] = []; queue.push({ t: target, s: source, d: 0 }); // BFS to ensure objects don't have recursive references at shallower depths. while (queue.length > 0) { - const { t, s, d } = map(queue.shift()); + const { t, s, d } = /** @type {!DeepMergeTuple} */ Object(queue.shift()); if (seen.includes(s)) { throw new Error('Source object has a circular reference.'); } @@ -154,13 +156,13 @@ export const objectsEqualShallow = ( * updates the object originally passed, and returns the value that was returned * by the factory function. * - * @param {T} obj - * @param {string} prop + * @param {T extends object} object + * @param {string} property * @param {function(T, string):R} factory * @returns {R} - * @template T,R + * @template P,T,R */ -export const memo = ( +export const memo = ( object: T, property: P, factory: (argument0: T, argument1: P) => T[P],