@@ -245,6 +245,8 @@ export function partialMatchKey(a: any, b: any): boolean {
245245 return false
246246}
247247
248+ const hasOwn = Object . prototype . hasOwnProperty
249+
248250/**
249251 * This function returns `a` if `b` is deeply equal.
250252 * If not, it will replace any deeply equal children of `b` with those of `a`.
@@ -258,37 +260,43 @@ export function replaceEqualDeep(a: any, b: any): any {
258260
259261 const array = isPlainArray ( a ) && isPlainArray ( b )
260262
261- if ( array || ( isPlainObject ( a ) && isPlainObject ( b ) ) ) {
262- const aItems = array ? a : Object . keys ( a )
263- const aSize = aItems . length
264- const bItems = array ? b : Object . keys ( b )
265- const bSize = bItems . length
266- const copy : any = array ? [ ] : { }
267- const aItemsSet = new Set ( aItems )
268-
269- let equalItems = 0
270-
271- for ( let i = 0 ; i < bSize ; i ++ ) {
272- const key = array ? i : bItems [ i ]
273- if (
274- ( ( ! array && aItemsSet . has ( key ) ) || array ) &&
275- a [ key ] === undefined &&
276- b [ key ] === undefined
277- ) {
278- copy [ key ] = undefined
279- equalItems ++
280- } else {
281- copy [ key ] = replaceEqualDeep ( a [ key ] , b [ key ] )
282- if ( copy [ key ] === a [ key ] && a [ key ] !== undefined ) {
283- equalItems ++
284- }
285- }
263+ if ( ! array && ! ( isPlainObject ( a ) && isPlainObject ( b ) ) ) return b
264+
265+ const aItems = array ? a : Object . keys ( a )
266+ const aSize = aItems . length
267+ const bItems = array ? b : Object . keys ( b )
268+ const bSize = bItems . length
269+ const copy : any = array ? new Array ( bSize ) : { }
270+
271+ let equalItems = 0
272+
273+ for ( let i = 0 ; i < bSize ; i ++ ) {
274+ const key : any = array ? i : bItems [ i ]
275+ const aItem = a [ key ]
276+ const bItem = b [ key ]
277+
278+ if ( aItem === bItem ) {
279+ copy [ key ] = aItem
280+ if ( array ? i < aSize : hasOwn . call ( a , key ) ) equalItems ++
281+ continue
282+ }
283+
284+ if (
285+ aItem === null ||
286+ bItem === null ||
287+ typeof aItem !== 'object' ||
288+ typeof bItem !== 'object'
289+ ) {
290+ copy [ key ] = bItem
291+ continue
286292 }
287293
288- return aSize === bSize && equalItems === aSize ? a : copy
294+ const v = replaceEqualDeep ( aItem , bItem )
295+ copy [ key ] = v
296+ if ( v === aItem ) equalItems ++
289297 }
290298
291- return b
299+ return aSize === bSize && equalItems === aSize ? a : copy
292300}
293301
294302/**
@@ -311,13 +319,12 @@ export function shallowEqualObjects<T extends Record<string, any>>(
311319 return true
312320}
313321
314- export function isPlainArray ( value : unknown ) {
322+ export function isPlainArray ( value : unknown ) : value is Array < unknown > {
315323 return Array . isArray ( value ) && value . length === Object . keys ( value ) . length
316324}
317325
318326// Copied from: https://github.com/jonschlinkert/is-plain-object
319- // eslint-disable-next-line @typescript-eslint/no-wrapper-object-types
320- export function isPlainObject ( o : any ) : o is Object {
327+ export function isPlainObject ( o : any ) : o is Record < PropertyKey , unknown > {
321328 if ( ! hasObjectPrototype ( o ) ) {
322329 return false
323330 }
0 commit comments