/** * Type that defines a deep partial generic object */ export type DeepPartial = { [K in keyof T]?: DeepPartial } /** * Deep merge two objects. * @param {T} target The source object to be merged * @param {DeepPartial} ...sources The values with the overrides * @returns {T} A new instance with the merged values */ export const deepMerge = (target: T, ...sources: Array | undefined>) => { if (!sources.length) { return target } const merged = { ...target } for (const source of sources) { if (!source) { continue } const keys = Object.keys(source) as Array for (const key of keys) { if (!(source[key] instanceof Array) && typeof source[key] === 'object' && typeof target[key] === 'object') { merged[key] = deepMerge(target[key], source[key]) } else if (source[key] !== undefined) { ;(merged[key] as any) = source[key] } } } return merged }