Nested data needs a copy at each level that changes.

nested copy When a nested object changes, copy the outer object and the inner object so unchanged references stay separate from updated data.

Nested Copies

nextCity
nested.ts
Replay: real traced execution (multi-file project)
type Address = {
    city: string;
    country: string;
};

type Profile = {
    name: string;
    address: Address;
};

const nextCity: string = "Paris";
const profile: Profile = {
    name: "Ada",
    address: { city: "London", country: "UK" },
};

const moved: Profile = {
    ...profile,
    address: { ...profile.address, city: nextCity },
};

console.log(`before=${profile.address.city}`);
console.log(`after=${moved.address.city}`);
type Address = {
    city: string;
    country: string;
};

type Profile = {
    name: string;
    address: Address;
};

const nextCity: string = "Tokyo";
const profile: Profile = {
    name: "Ada",
    address: { city: "London", country: "UK" },
};

const moved: Profile = {
    ...profile,
    address: { ...profile.address, city: nextCity },
};

console.log(`before=${profile.address.city}`);
console.log(`after=${moved.address.city}`);
type Address = {
    city: string;
    country: string;
};

type Profile = {
    name: string;
    address: Address;
};

const nextCity: string = "Lima";
const profile: Profile = {
    name: "Ada",
    address: { city: "London", country: "UK" },
};

const moved: Profile = {
    ...profile,
    address: { ...profile.address, city: nextCity },
};

console.log(`before=${profile.address.city}`);
console.log(`after=${moved.address.city}`);
  1. nextCity ← Paris, profile ← [object Object], moved ← [object Object]

    8    address: Address;9};1011const nextCity→ Paris: string = "Paris";  //@nextCity="Tokyo", "Lima"12const profile→ [object Object]: Profile = {13    name: "Ada",14    address: { city: "London", country: "UK" },15};1617const moved→ [object Object]: Profile = {18    ...profile[object Object],19    address: { ...profile.address[object Object], city: nextCityParis },20};2122console.log(`before=${profile.address.cityLondon}`);23console.log(`after=${moved.address.cityParis}`);
    outputbefore=London
    after=Paris
  1. nextCity ← Tokyo, profile ← [object Object], moved ← [object Object]

    8    address: Address;9};1011const nextCity→ Tokyo: string = "Tokyo";12const profile→ [object Object]: Profile = {13    name: "Ada",14    address: { city: "London", country: "UK" },15};1617const moved→ [object Object]: Profile = {18    ...profile[object Object],19    address: { ...profile.address[object Object], city: nextCityTokyo },20};2122console.log(`before=${profile.address.cityLondon}`);23console.log(`after=${moved.address.cityTokyo}`);
    outputbefore=London
    after=Tokyo
  1. nextCity ← Lima, profile ← [object Object], moved ← [object Object]

    8    address: Address;9};1011const nextCity→ Lima: string = "Lima";12const profile→ [object Object]: Profile = {13    name: "Ada",14    address: { city: "London", country: "UK" },15};1617const moved→ [object Object]: Profile = {18    ...profile[object Object],19    address: { ...profile.address[object Object], city: nextCityLima },20};2122console.log(`before=${profile.address.cityLondon}`);23console.log(`after=${moved.address.cityLima}`);
    outputbefore=London
    after=Lima