import { isNullish } from './nullish' ; param obj param properties returns export function propertyExists ( obj , ... properties ) { if ( ! properties . length ) { return true ; } if ( obj && obj . hasOwnProperty ( properties [ 0 ] ) ) { return propertyExists ( obj [ properties [ 0 ] ] , ... properties . slice ( 1 ) ) ; } return false ; } param keyMapping param obj returns export const renameKeys = ( keyMapping , obj ) : Record < string , any > => { const unchangedEntries = Object . keys ( obj ) . filter ( k => ! Object . keys ( keyMapping ) . includes ( k ) ) . reduce ( ( newObj , key ) => ( { ... newObj , [ key ] : obj [ key ] } ) , { } ) ; return Object . entries ( keyMapping ) . reduce ( ( newObj , [ oldKey , newKey ] ) => ( { ... newObj , [ newKey ] : obj [ oldKey ] } ) , unchangedEntries ) ; } ; param keys param obj returns export const pick = < T > ( keys , obj ) : Partial < T > => { const result = { } ; keys . forEach ( key => { const value = obj [ key ] ; if ( Object . keys ( obj ) . includes ( key ) ) { result [ key ] = value ; } } ) ; return result ; } ; param keys param obj returns export const exclude = < T > ( keys , obj ) : Partial < T > => { const result = { } ; Object . keys ( obj ) . forEach ( key => { const value = obj [ key ] ; if ( ! keys . includes ( key ) ) { result [ key ] = value ; } } ) ; return result ; } ; param key param value param obj returns export const assoc = < T > ( key , value , obj ) : T & { [ key ] : any ; } => ( { ... obj , [ key ] : value } ) ; param key param value returns export function toSanitizedObject ( key , value ) { return isNullish ( key ) || isNullish ( value ) ? { } : { [ key ] : value } ; } param obj param keys returns export function pickIgnoreCase < T extends Record < string , any > > ( obj = { } as T , ... keys ) { return keys . reduce ( ( filteredHeaders , providedKey ) => { const originalKey = Object . keys ( obj ) . find ( objKey => objKey . toLowerCase ( ) === providedKey . toLowerCase ( ) ) ; return { ... filteredHeaders , ... ( originalKey && { [ originalKey ] : obj [ originalKey ] } ) } ; } , { } ) ; } param obj param key returns export function pickValueIgnoreCase < T extends Record < string , any > > ( obj = { } as T , key ) { return Object . values ( pickIgnoreCase ( obj , key ) ) [ 0 ] ; } param obj returns export function pickNonNullish < T extends Record < string , any > > ( obj = { } as T ) { return Object . entries ( obj ) . filter ( ( [ key , value ] ) => ! isNullish ( key ) && ! isNullish ( value ) ) . reduce ( ( filtered , [ key , value ] ) => ( { ... filtered , [ key ] : value } ) , { } ) ; } param left param right returns export function mergeLeftIgnoreCase < LeftT extends Record < string , any > , RightT extends Record < string , any > > ( left = { } as LeftT , right = { } as RightT ) { return Object . entries ( left ) . map ( ( [ key , value ] ) => pickValueIgnoreCase ( right , key ) ? pickIgnoreCase ( right , key ) : { [ key ] : value } ) . reduce ( ( replaced , obj ) => ( { ... replaced , ... obj } ) , { } ) ; } param left param right returns export function mergeIgnoreCase < LeftT extends Record < string , any > , RightT extends Record < string , any > > ( left = { } as LeftT , right = { } as RightT ) { return { ... mergeLeftIgnoreCase ( left , right ) , ... right } ; }