Execute Program

Everyday TypeScript: Object Spread

Welcome to the Object Spread lesson!

This lesson is shown as static text below. However, it's designed to be used interactively. Click the button below to start!

  • The spread operator, ..., copies an existing object's properties into a new object. The new object also includes any new properties that we specify.

  • >
    const partialAmir = {name: 'Amir'};
    const fullAmir = {...partialAmir, admin: true};
    fullAmir;
    Result:
    {name: 'Amir', admin: true}Pass Icon
  • TypeScript supports object spread and, as usual, it enforces the objects' types. If we try to spread an object whose properties have the wrong types, we'll get a type error.

  • >
    /* Note that Amir is NOT defined using the User type below. His type for
    the `admin` property is `number`! */
    const amir = {name: 'Amir', admin: 1};

    type User = {
    name: string
    admin: boolean
    };

    const betty: User = {...amir, name: 'Betty'};
    betty.admin;
    Result:
    type error: Type '{ name: string; admin: number; }' is not assignable to type 'User'.
      Types of property 'admin' are incompatible.
        Type 'number' is not assignable to type 'boolean'.Pass Icon
  • When defining betty: User, we tried to spread an admin: number property. But User has admin: boolean. That's a type error.

  • Ordering is very important with spread. If we put a property after the spread, like {...amir, name: 'Betty'}, then we overwrite the original object's property. But if we put the spread at the end, like {name: 'Betty', ...amir}, then the original object's property "wins".

  • >
    const amir = {name: 'Amir', admin: true};
    const betty = {...amir, name: 'Betty'};
    betty.name;
    Result:
    'Betty'Pass Icon
  • What if we reverse that spread by writing const betty = {name: 'Betty', ...amir}? In JavaScript, the name property from amir wins, and betty.name is 'Amir'. Our explicit name: 'Betty' property is ignored. That's probably not what we intended when writing that code!

  • Fortunately, TypeScript catches this mistake. If we specify an explicit property, but then later overwrite it with a spread, that's a type error.

  • >
    const amir = {name: 'Amir', admin: true};
    const betty = {name: 'Betty', ...amir};
    betty.name;
    Result:
    type error: 'name' is specified more than once, so this usage will be overwritten.Pass Icon
  • Here's a code problem:

    In the code example below, we're trying to replace the country object's name. We mixed up the property order, causing a type error. Fix the order so that the property is actually overwritten.

    const countryWithOldName = {name: 'Ceylon', population: 21919000};
    const countryWithNewName = {
    ...countryWithOldName,
    name: 'Sri Lanka',
    };
    ; /* This extra semicolon prevents a potential problem when your answer doesn't
    * end in a semicolon. */
    [countryWithNewName.name, countryWithNewName.population];
    Goal:
    ['Sri Lanka', 21919000]
    Yours:
    ['Sri Lanka', 21919000]Pass Icon