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}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 forthe `admin` property is `number`! */const amir = {name: 'Amir', admin: 1};type User = {name: stringadmin: 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'.When defining
betty: User, we tried to spread anadmin: numberproperty. ButUserhasadmin: 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'
What if we reverse that spread by writing
const betty = {name: 'Betty', ...amir}? In JavaScript, thenameproperty fromamirwins, andbetty.nameis'Amir'. Our explicitname: '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.
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]