# merge

```ts
import { merge } from 'cx/data';
```


`merge` performs an immutable merge of properties into an object. Supports deep paths using dot notation (e.g., `"address.city"`).

```tsx
import { merge, updateArray, createModel } from "cx/data";
import { Controller, KeySelection } from "cx/ui";
import { Button, Grid, NumberField } from "cx/widgets";

interface User {
  id: number;
  name: string;
  score: number;
  level: number;
}

interface Model {
  users: User[];
  selectedId: number;
  bonusPoints: number;
}

const m = createModel<Model>();

class PageController extends Controller {
  onInit() {
    this.store.set(m.users, [
      { id: 1, name: "Alice", score: 100, level: 1 },
      { id: 2, name: "Bob", score: 150, level: 2 },
      { id: 3, name: "Carol", score: 80, level: 1 },
    ]);
    this.store.set(m.selectedId, 1);
    this.store.set(m.bonusPoints, 50);
  }

  addBonus() {
    const selectedId = this.store.get(m.selectedId);
    const bonus = this.store.get(m.bonusPoints);

    this.store.update(m.users, (users) =>
      updateArray(
        users,
        (user) => merge(user, { score: user.score + bonus }),
        (user) => user.id === selectedId,
      ),
    );
  }

  levelUp() {
    const selectedId = this.store.get(m.selectedId);

    this.store.update(m.users, (users) =>
      updateArray(
        users,
        (user) => merge(user, { level: user.level + 1 }),
        (user) => user.id === selectedId,
      ),
    );
  }

  reset() {
    this.onInit();
  }
}

export default (
  <div controller={PageController}>
    <Grid
      records={m.users}
      selection={{ type: KeySelection, bind: m.selectedId, keyField: "id" }}
      columns={[
        { header: "Name", field: "name" },
        { header: "Score", field: "score", align: "right" },
        { header: "Level", field: "level", align: "center" },
      ]}
    />
    <div style="margin-top: 16px; display: flex; gap: 8px; align-items: center; flex-wrap: wrap">
      <NumberField value={m.bonusPoints} style="width: 80px" />
      <Button onClick="addBonus">Add Bonus</Button>
      <Button onClick="levelUp">Level Up</Button>
      <Button onClick="reset">Reset</Button>
    </div>
  </div>
);

```

## Signature

```ts
function merge<T extends object>(item: T, data?: Partial<T>): T
```

## Parameters

| Parameter | Type         | Description                          |
| --------- | ------------ | ------------------------------------ |
| `item`    | `T`          | The object to merge into.            |
| `data`    | `Partial<T>` | Properties to merge.                 |

## Return Value

Returns a new object with merged properties.

## Examples

### Basic usage

```ts
const user = { id: 1, name: "Alice", score: 100 };
const updated = merge(user, { score: 150 });
// { id: 1, name: "Alice", score: 150 }

// Original is unchanged
console.log(user.score); // 100
```

### Deep paths

```ts
const user = {
  id: 1,
  address: { city: "NYC", zip: "10001" },
};

const updated = merge(user, { "address.city": "LA" });
// { id: 1, address: { city: "LA", zip: "10001" } }
```

### With updateArray

```ts
const users = [
  { id: 1, name: "Alice", active: true },
  { id: 2, name: "Bob", active: false },
];

const updated = updateArray(
  users,
  (user) => merge(user, { active: true }),
  (user) => user.id === 2,
);
// [{ id: 1, name: "Alice", active: true }, { id: 2, name: "Bob", active: true }]
```

## See Also

- [updateArray](/docs/utilities/update-array) - Update items in array
- [updateTree](/docs/utilities/update-tree) - Update nodes in tree