jet-validators
Version:
Fast, zero-dependency TypeScript validators and utilities for runtime checks, parsing, and lightweight object schema validation.
60 lines (59 loc) • 1.72 kB
JavaScript
function deepClone(value) {
if (value === null || typeof value !== 'object') {
return value;
}
if (Array.isArray(value)) {
return cloneArray(value);
}
const proto = Object.getPrototypeOf(value);
if (proto === Object.prototype || proto === null) {
return cloneRecord(value);
}
return cloneExotic(value);
}
function cloneArray(source) {
const out = new Array(source.length);
for (let i = 0; i < source.length; i++) {
out[i] = deepClone(source[i]);
}
return out;
}
function cloneRecord(source) {
const out = {};
const keys = Object.keys(source);
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
out[key] = deepClone(source[key]);
}
return out;
}
function cloneExotic(value) {
if (value instanceof Date)
return new Date(value.getTime());
if (value instanceof RegExp)
return new RegExp(value.source, value.flags);
if (value instanceof Map) {
const out = new Map();
for (const [k, v] of value)
out.set(deepClone(k), deepClone(v));
return out;
}
if (value instanceof Set) {
const out = new Set();
for (const v of value)
out.add(deepClone(v));
return out;
}
if (ArrayBuffer.isView(value)) {
return new value.constructor(value.buffer.slice(value.byteOffset, value.byteOffset + value.byteLength));
}
if (value instanceof ArrayBuffer) {
return value.slice(0);
}
const out = Object.create(Object.getPrototypeOf(value));
for (const key of Object.keys(value)) {
out[key] = deepClone(value[key]);
}
return out;
}
export default deepClone;