associate
Immutably set object properties with shallow or deep cloning
Immutably set object properties, returning a new copy with the updated value. Provides both shallow (associate) and deep (associateDeep) cloning variants.
Usage
import { associate, associateDeep, assoc, assocDeep } from '@accelint/core';
const person = {
name: 'Alice',
address: {
city: 'New York',
street: '123 Main St'
}
};
// Shallow copy
const updated = associate(person)('name')('Bob');
// { name: 'Bob', address: { city: 'New York', street: '123 Main St' } }
// Note: address reference is shared
// Deep copy
const deepUpdated = associateDeep(person)('address')({
city: 'Austin',
street: '987 Sample St'
});
// { name: 'Alice', address: { city: 'Austin', street: '987 Sample St' } }
// Note: address is a new objectReference
associate
function associate<T extends object>(
obj: T
): <K extends keyof T>(prop: K) => (val: T[K]) => TParameters
| Parameter | Type | Description |
|---|---|---|
obj | T extends object | The object to update |
Returns
Returns a curried function that accepts a property name, then accepts a value, returning a new shallow copy of the object with the updated property.
Type Parameters
T- The type of the input objectK- The property key type
Aliases
assoc- Shorter alias forassociate
associateDeep
function associateDeep<T extends object>(
obj: T
): <K extends keyof T>(prop: K) => (val: T[K]) => TParameters
| Parameter | Type | Description |
|---|---|---|
obj | T extends object | The object to update |
Returns
Returns a curried function that accepts a property name, then accepts a value, returning a new deep copy of the object with the updated property.
Uses structuredClone() internally for deep cloning.
Aliases
assocDeep- Shorter alias forassociateDeep
Examples
Example: Updating nested state
import { associate } from '@accelint/core';
const state = {
user: { id: 1, name: 'Alice' },
settings: { theme: 'dark' }
};
// Create updater for user property
const setUser = associate(state)('user');
const newState = setUser({ id: 1, name: 'Bob' });
// { user: { id: 1, name: 'Bob' }, settings: { theme: 'dark' } }Example: Partial application for reusable setters
import { associateDeep } from '@accelint/core';
interface Config {
apiKey: string;
endpoint: string;
timeout: number;
}
const config: Config = {
apiKey: 'abc123',
endpoint: 'https://api.example.com',
timeout: 5000
};
// Create reusable setter
const updateTimeout = associateDeep(config)('timeout');
updateTimeout(10000);
// { apiKey: 'abc123', endpoint: 'https://api.example.com', timeout: 10000 }Example: Shallow vs deep cloning
import { associate, associateDeep } from '@accelint/core';
const original = {
data: { values: [1, 2, 3] },
meta: { count: 3 }
};
// Shallow: nested objects are shared
const shallow = associate(original)('meta')({ count: 5 });
original.data === shallow.data; // true (same reference)
// Deep: nested objects are cloned
const deep = associateDeep(original)('meta')({ count: 5 });
original.data === deep.data; // false (different reference)Example: Composing with pipe
import { pipe, associateDeep } from '@accelint/core';
interface User {
name: string;
email: string;
active: boolean;
}
const updateUser = pipe(
associateDeep<User>({ name: '', email: '', active: false })('name'),
(user) => associateDeep(user)('active')(true)
);
updateUser('Alice');
// { name: 'Alice', email: '', active: true }Good to know:
associatecreates a shallow copy using spread ({ ...obj }), whileassociateDeepusesstructuredClone()for full deep cloning. Use shallow for performance when nested objects don't need independent copies. Use deep when you need complete immutability.