@szydlovski/deep-object
Version:
utility functions for deeply nested objects
57 lines (48 loc) • 1.67 kB
text/typescript
import { _deepObjectTraverse } from './core.js';
function validatePath(path: KeyPath): string[] {
if (typeof path === 'string') {
return path.split('.');
} else if (Array.isArray(path)) {
return [...path];
} else {
throw new TypeError(`Path is not a string or an array`);
}
}
export type KeyPath = string | string[];
function extractDeepProperty<T = any>(target: object, keyPath: KeyPath): [true, T] | [false, undefined] {
const path = validatePath(keyPath);
const key = path.pop();
if (!key) throw new TypeError('Cannot extract deep property from an empty path');
try {
const position = _deepObjectTraverse(target, path, false);
const exists = Object.keys(position).includes(key);
const value = position[key];
return [exists, value];
} catch {
return [false, undefined];
}
}
function hasDeepProperty(target: object, keyPath: KeyPath): boolean {
return extractDeepProperty(target, keyPath)[0];
}
function getDeepProperty<T = any>(target: object, keyPath: KeyPath): T | undefined {
return extractDeepProperty(target, keyPath)[1];
}
function setDeepProperty(target: object, keyPath: KeyPath, value: any): object {
const path = validatePath(keyPath);
const key = path.pop();
if (!key) throw new TypeError('Cannot set deep property on an empty path');
const position = _deepObjectTraverse(target, path);
position[key] = value;
return target;
}
export {
extractDeepProperty,
hasDeepProperty,
getDeepProperty,
setDeepProperty,
extractDeepProperty as extractProperty,
hasDeepProperty as hasProperty,
getDeepProperty as getProperty,
setDeepProperty as setProperty,
};