56 lines
1018 B
TypeScript
56 lines
1018 B
TypeScript
|
|
||
|
import { assert } from "tsafe/assert";
|
||
|
import { is } from "tsafe/is";
|
||
|
|
||
|
export function deepAssign(
|
||
|
params: {
|
||
|
target: Record<string, unknown>;
|
||
|
source: Record<string, unknown>;
|
||
|
}
|
||
|
) {
|
||
|
|
||
|
const { target, source } = params;
|
||
|
|
||
|
Object.keys(source).forEach(key => {
|
||
|
var dereferencedSource = source[key];
|
||
|
|
||
|
if (
|
||
|
target[key] === undefined ||
|
||
|
!(dereferencedSource instanceof Object)
|
||
|
) {
|
||
|
|
||
|
Object.defineProperty(
|
||
|
target,
|
||
|
key,
|
||
|
{
|
||
|
"enumerable": true,
|
||
|
"value": dereferencedSource
|
||
|
}
|
||
|
);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const dereferencedTarget = target[key];
|
||
|
|
||
|
if (dereferencedSource instanceof Array) {
|
||
|
|
||
|
assert(is<unknown[]>(dereferencedTarget));
|
||
|
assert(is<unknown[]>(dereferencedSource));
|
||
|
|
||
|
dereferencedSource.forEach(entry => dereferencedTarget.push(entry));
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
assert(is<Record<string, unknown>>(dereferencedTarget));
|
||
|
assert(is<Record<string, unknown>>(dereferencedSource));
|
||
|
|
||
|
deepAssign({
|
||
|
"target": dereferencedTarget,
|
||
|
"source": dereferencedSource
|
||
|
});
|
||
|
|
||
|
});
|
||
|
|
||
|
}
|