Object Utilities
Object utilities provide robust tools to manipulate, compare, and traverse objects in a type-safe, ergonomic way. Use these helpers for cloning, diffing, nested path access, caching, and more.
📚 Quick Reference
Problem
Implement 📚 quick reference in a production-friendly way with @vielzeug/toolkit while keeping setup and cleanup explicit.
Runnable Example
The snippet below is copy-paste runnable in a TypeScript project with @vielzeug/toolkit installed.
stash: Key-value cache with automatic GC and observer support.deepClone: Deep clone nested values and common JS structures.defaults: Apply fallback values for undefined keys.diff: Compare two objects and return the structural differences.entries: Typed wrapper for Object.entries.filterValues: Filter object keys by value predicate.fromEntries: Typed wrapper for Object.fromEntries.has: Type-safe key existence check.invert: Invert key-value pairs.keys: Typed wrapper for Object.keys.mapKeys: Transform object keys.mapValues: Transform object values.deepMergeandshallowMerge: Merge multiple objects.pick: Create a new object with only selected keys.omit: Create a new object excluding selected keys.parseJSON: Safely parse JSON strings with optional fallback value.get: Safely access nested properties using dot-notation strings.prune: Recursively remove null/undefined/empty values.seek: Recursively search nested values by similarity threshold.values: Typed wrapper for Object.values.
💡 Practical Examples
Cloning & Diffing
ts
import { deepClone, diff } from '@vielzeug/toolkit';
const config = { api: { host: 'localhost', port: 8080 }, flags: { beta: false } };
const finalConfig = deepClone(config);
finalConfig.api.port = 3000;
finalConfig.flags.beta = true;
// Find what changed
const changes = diff(config, finalConfig);
// { api: { port: 3000 }, flags: { beta: true } }Deep vs Shallow Merge
ts
import { deepMerge, shallowMerge } from '@vielzeug/toolkit';
const base = { api: { host: 'localhost', port: 8080 }, tags: ['core'] };
const override = { api: { port: 3000 }, tags: ['docs'] };
const deep = deepMerge(base, override);
// { api: { host: 'localhost', port: 3000 }, tags: ['core', 'docs'] }
const shallow = shallowMerge(base, override);
// { api: { port: 3000 }, tags: ['docs'] }
console.log(deep, shallow);Accessing Nested Data
ts
import { get, omit, pick, seek } from '@vielzeug/toolkit';
const data = {
user: {
profile: {
settings: { theme: 'dark' },
},
},
};
// Access via path string
const theme = get(data, 'user.profile.settings.theme'); // 'dark'
// Search values anywhere in the object
const hasDark = seek(data, 'dark'); // true
const user = { id: 1, name: 'Alice', role: 'admin', password: 'secret' };
const safe = pick(user, ['id', 'name', 'role']);
const noSecret = omit(user, ['password']);
console.log(theme, hasDark, safe, noSecret);Pruning & Cleaning
ts
import { prune } from '@vielzeug/toolkit';
// Remove all nulls, undefined, empty strings, and empty objects/arrays
prune({ a: 1, b: null, c: '', d: { e: undefined } }); // { a: 1 }
prune([1, null, '', 2, undefined]); // [1, 2]
prune(' hello '); // 'hello'
prune(' '); // undefinedCaching
ts
import { stash } from '@vielzeug/toolkit';
const myCache = stash<string>({ hash: (key) => JSON.stringify(key) });
myCache.set(['user', 1], 'John Doe');
myCache.get(['user', 1]); // 'John Doe'
myCache.scheduleGc(['user', 1], 5000); // Auto-delete after 5s
myCache.size(); // 1🔗 All Object Utilities
- stash
- deepClone
- defaults
- diff
- entries
- filterValues
- fromEntries
- has
- invert
- keys
- mapKeys
- mapValues
- deepMerge and shallowMerge
- pick
- omit
- parseJSON
- get
- prune
- seek
- values
Expected Output
- The example runs without type errors in a standard TypeScript setup.
- The main flow produces the behavior described in the recipe title.
Common Pitfalls
- Forgetting cleanup/dispose calls can leak listeners or stale state.
- Skipping explicit typing can hide integration issues until runtime.
- Not handling error branches makes examples harder to adapt safely.