deprecated export type IKeyWhitelist < T > = IKeyAllowlist < T > ; deprecated export type IKeyBlacklist < T > = IKeyDenylist < T > ; deprecated export interface IKeyAllowlist < T > { include : Array < keyof T > ; } export type KeyAllowlist < T > = IKeyAllowlist < T > ; deprecated export interface IKeyDenylist < T > { exclude : Array < keyof T > ; } export type KeyDenylist < T > = IKeyDenylist < T > ; /**
 * Returns true if the arrays are equal. Elements will be shallowly compared by
 * default, or they will be compared using the custom `compare` function if one
 * is provided.
 */ export function arraysEqual ( arrA , arrB , compare = ( a , b ) => a === b ) { if ( arrA == null && arrB == null ) { return true ; } else if ( arrA == null || arrB == null || arrA . length !== arrB . length ) { return false ; } else { return arrA . every ( ( a , i ) => compare ( a , arrB [ i ] ) ) ; } } returns export function shallowCompareKeys < T extends { } > ( objA , objB , keys ? ) { if ( objA == null && objB == null ) { return true ; } else if ( objA == null || objB == null ) { return false ; } else if ( Array . isArray ( objA ) || Array . isArray ( objB ) ) { return false ; } else if ( keys != null ) { return shallowCompareKeysImpl ( objA , objB , keys ) ; } else { const keysA = Object . keys ( objA ) as Array < keyof T > ; const keysB = Object . keys ( objB ) as Array < keyof T > ; return ( shallowCompareKeysImpl ( objA , objB , { include : keysA } ) && shallowCompareKeysImpl ( objA , objB , { include : keysB } ) ) ; } } returns export function deepCompareKeys ( objA , objB , keys ? ) { if ( objA === objB ) { return true ; } else if ( objA == null && objB == null ) { return true ; } else if ( objA == null || objB == null ) { return false ; } else if ( Array . isArray ( objA ) || Array . isArray ( objB ) ) { return arraysEqual ( objA , objB , deepCompareKeys ) ; } else if ( isSimplePrimitiveType ( objA ) || isSimplePrimitiveType ( objB ) ) { return objA === objB ; } else if ( keys != null ) { return deepCompareKeysImpl ( objA , objB , keys ) ; } else if ( objA . constructor !== objB . constructor ) { return false ; } else { const keysA = Object . keys ( objA ) ; const keysB = Object . keys ( objB ) ; if ( keysA == null || keysB == null ) { return false ; } if ( keysA . length === 0 && keysB . length === 0 ) { return true ; } return arraysEqual ( keysA , keysB ) && deepCompareKeysImpl ( objA , objB , keysA ) ; } } /**
 * Returns a descriptive object for each key whose values are deeply unequal
 * between two provided objects. Useful for debugging shouldComponentUpdate.
 */ export function getDeepUnequalKeyValues < T extends { } > ( objA = ( { } as any ) as T , objB = ( { } as any ) as T , keys ? ) { const filteredKeys = keys == null ? unionKeys ( objA , objB ) : keys ; return getUnequalKeyValues ( objA , objB , filteredKeys , ( a , b , key ) => { return deepCompareKeys ( a , b , [ key ] ) ; } ) ; } /**
 * Partial shallow comparison between objects using the given list of keys.
 */ function shallowCompareKeysImpl < T extends object > ( objA , objB , keys ) { return filterKeys ( objA , objB , keys ) . every ( key => { return objA . hasOwnProperty ( key ) === objB . hasOwnProperty ( key ) && objA [ key ] === objB [ key ] ; } ) ; } /**
 * Partial deep comparison between objects using the given list of keys.
 */ function deepCompareKeysImpl ( objA , objB , keys ) { return keys . every ( key => { return objA . hasOwnProperty ( key ) === objB . hasOwnProperty ( key ) && deepCompareKeys ( objA [ key ] , objB [ key ] ) ; } ) ; } function isSimplePrimitiveType ( value ) { return typeof value === "number" || typeof value === "string" || typeof value === "boolean" ; } function filterKeys < T > ( objA , objB , keys ) { if ( isAllowlist ( keys ) ) { return keys . include ; } else if ( isDenylist ( keys ) ) { const keysA = Object . keys ( objA ) ; const keysB = Object . keys ( objB ) ; const keySet = arrayToObject ( keysA . concat ( keysB ) ) ; keys . exclude . forEach ( key => delete keySet [ key ] ) ; return Object . keys ( keySet ) as Array < keyof T > ; } return [ ] ; } function isAllowlist < T > ( keys ) { return keys != null && ( keys as KeyAllowlist < T > ) . include != null ; } function isDenylist < T > ( keys ) { return keys != null && ( keys as KeyDenylist < T > ) . exclude != null ; } function arrayToObject ( arr ) { return arr . reduce ( ( obj , element ) => { obj [ element ] = true ; return obj ; } , { } ) ; } function getUnequalKeyValues < T extends { } > ( objA , objB , keys , compareFn ) { const unequalKeys = keys . filter ( key => ! compareFn ( objA , objB , key ) ) ; const unequalKeyValues = unequalKeys . map ( key => ( { key , valueA : objA [ key ] , valueB : objB [ key ] , } ) ) ; return unequalKeyValues ; } function unionKeys < T extends { } > ( objA , objB ) { const keysA = Object . keys ( objA ) ; const keysB = Object . keys ( objB ) ; const concatKeys = keysA . concat ( keysB ) ; const keySet = arrayToObject ( concatKeys ) ; return Object . keys ( keySet ) as Array < keyof T > ; }