49 lines
1.2 KiB
TypeScript
49 lines
1.2 KiB
TypeScript
/**
|
|
* Simple object check.
|
|
* @param item
|
|
* @returns {boolean}
|
|
*/
|
|
export function isObject(item: unknown): item is Record<string, unknown> {
|
|
return !!item && typeof item === 'object' && !Array.isArray(item)
|
|
}
|
|
|
|
/**
|
|
* Deep merge two objects.
|
|
* @param target
|
|
* @param ...sources
|
|
*/
|
|
export function mergeDeep(
|
|
target: Record<string, unknown>,
|
|
...sources: Record<string, unknown>[]
|
|
): Record<string, unknown> {
|
|
if (!sources.length) {
|
|
return target
|
|
}
|
|
const source = sources.shift()
|
|
|
|
if (isObject(target) && isObject(source)) {
|
|
for (const key in source) {
|
|
if (isObject(source[key])) {
|
|
if (!target[key]) {
|
|
Object.assign(target, { [key]: {} })
|
|
}
|
|
mergeDeep(
|
|
target[key] as Record<string, unknown>,
|
|
source[key] as Record<string, unknown>
|
|
)
|
|
} else if (Array.isArray(target[key]) && Array.isArray(source[key])) {
|
|
return (target[key] as unknown[]).map((el, i) =>
|
|
mergeDeep(
|
|
el as Record<string, unknown>,
|
|
(source[key] as unknown[])[i] as Record<string, unknown>
|
|
)
|
|
) as unknown as Record<string, unknown>
|
|
} else {
|
|
Object.assign(target, { [key]: source[key] })
|
|
}
|
|
}
|
|
}
|
|
|
|
return mergeDeep(target, ...sources)
|
|
}
|