export function isExist ( value ) { return ! isUndefined ( value ) && ! isNull ( value ) ; } export function isDate ( value ) { return value instanceof Date ; } export function isUndefined ( value ) { return typeof value === 'undefined' ; } export function isNull ( value ) { return value === null ; } export function isBoolean ( value ) { return typeof value === 'boolean' ; } export function isNumber ( value ) { return typeof value === 'number' ; } export function isString ( value ) { return typeof value === 'string' ; } export function isInteger ( value ) { return isNumber ( value ) && isFinite ( value ) && Math . floor ( value ) === value ; } export function isObject ( obj ) { return typeof obj === 'object' && obj !== null ; } export function isFunction ( value ) { return typeof value === 'function' ; } export function range ( start , stop ? , step ? ) { if ( isUndefined ( stop ) ) { stop = start || 0 ; start = 0 ; } step = step || 1 ; const arr = [ ] ; if ( stop ) { const flag = step < 0 ? - 1 : 1 ; stop *= flag ; for ( ; start * flag < stop ; start += step ) { arr . push ( start ) ; } } return arr ; } export function pickProperty ( target , keys ) { const { length } = keys ; if ( length ) { for ( let i = 0 ; i < length ; i += 1 ) { if ( isUndefined ( target ) || isNull ( target ) ) { return null ; } target = target [ keys [ i ] ] ; } } return target ; } export function deepMergedCopy < T1 extends Record < string , any > , T2 extends Record < string , any > > ( targetObj , obj ) { const resultObj = { ... targetObj } as T1 & T2 ; Object . keys ( obj ) . forEach ( ( prop ) => { if ( isObject ( resultObj [ prop ] ) ) { if ( Array . isArray ( obj [ prop ] ) ) { resultObj [ prop as keyof T1 & T2 ] = deepCopyArray ( obj [ prop ] ) ; } else if ( resultObj . hasOwnProperty ( prop ) ) { resultObj [ prop ] = deepMergedCopy ( resultObj [ prop ] , obj [ prop ] ) ; } else { resultObj [ prop as keyof T1 & T2 ] = deepCopy ( obj [ prop ] ) ; } } else { resultObj [ prop as keyof T1 & T2 ] = obj [ prop ] ; } } ) ; return resultObj ; } export function deepCopyArray < T extends Array < any > > ( items ) { return items . map ( ( item ) => { if ( isObject ( item ) ) { return Array . isArray ( item ) ? deepCopyArray ( item ) : deepCopy ( item ) ; } return item ; } ) as T ; } export function deepCopy < T extends Record < string , any > > ( obj ) { const resultObj = { } as T ; const keys = Object . keys ( obj ) ; if ( ! keys . length ) { return obj ; } keys . forEach ( ( prop ) => { if ( isObject ( obj [ prop ] ) ) { resultObj [ prop ] = Array . isArray ( obj [ prop ] ) ? deepCopyArray ( obj [ prop ] ) : deepCopy ( obj [ prop ] ) ; } else { resultObj [ prop ] = obj [ prop ] ; } } ) ; return resultObj as T ; } export function pickPropertyWithMakeup ( target , args ) { const { length } = args ; if ( length ) { for ( let i = 0 ; i < length ; i += 1 ) { if ( isUndefined ( target [ args [ i ] ] ) ) { target [ args [ i ] ] = { } ; } target = target [ args [ i ] ] ; } } return target ; } export function forEach < T extends object , K extends Extract < keyof T , string > , V extends T [ K ] > ( obj , cb ) { for ( const key in obj ) { if ( obj . hasOwnProperty ( key ) ) { cb ( obj [ key as K ] as V , key as K ) ; } } } export function debounce ( fn , delay = 0 ) { let timer ; function debounced ( ... args ) { window . clearTimeout ( timer ) ; timer = window . setTimeout ( ( ) => { fn ( ... args ) ; } , delay ) ; } return debounced ; } export function isSameArray ( arr1 , arr2 ) { if ( arr1 . length !== arr2 . length ) { return false ; } for ( let i = 0 ; i < arr1 . length ; i += 1 ) { if ( arr1 [ i ] !== arr2 [ i ] ) { return false ; } } return true ; } export function getFirstValidValue ( values ) { return values ?. find ( ( value ) => value !== null ) ; }