import { assert } from "tsafe/assert"; import { is } from "tsafe/is"; //Warning: Be mindful that because of array this is not idempotent. export function deepAssign(params: { target: Record; source: Record }) { 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, "writable": true, "configurable": true, "value": dereferencedSource, }); return; } const dereferencedTarget = target[key]; if (dereferencedSource instanceof Array) { assert(is(dereferencedTarget)); assert(is(dereferencedSource)); dereferencedSource.forEach(entry => dereferencedTarget.push(entry)); return; } assert(is>(dereferencedTarget)); assert(is>(dereferencedSource)); deepAssign({ "target": dereferencedTarget, "source": dereferencedSource, }); }); }