liveBook · Manning

Spread operator

As explained in Essential TypeScript 5, Third Edition

Spread syntax is JavaScript syntax that expands the properties or elements of an existing object or iterable into a new expression.

The JavaScript spread operator, written `...`, expands array elements or object properties into a new expression. It is useful when passing an array to a function, combining arrays, or building an object from existing properties. section 3.4.1 section 3.5.2

Expand an array

In `index.js`, place `...` before the array being expanded: ```js let names = ["Hat", "Boots"]; let prices = [100, 50.25]; let combined = [...names, ...prices]; ``` `combined` contains the names followed by the prices. The same syntax passes array elements as separate arguments: `sumPrices(...prices)`. section 3.4.1

Build an object from existing properties

In `index.js`, spread an object inside an object literal: ```js let hat = { name: "Hat", price: 100 }; let otherHat = { ...hat }; let discountedHat = { ...hat, price: 10, discounted: true }; ``` `otherHat` receives `hat`’s properties. In `discountedHat`, the later `price` wins, while `discounted` adds a property. Put an overriding value *after* the spread. section 3.5.2

Do not confuse spread with rest syntax. Both use `...`, but `{ price, ...someProperties } = hat` collects the properties *not* selected as `price` into `someProperties`; `{ ...hat }` expands properties into a new object. section 3.5.2

Listing 2.19 Providing access to items in the todoCollection.ts file in the src folder
import { TodoItem } from "./todoItem";

export class TodoCollection {
    private nextId: number = 1;
    private itemMap = new Map<number, TodoItem>();
    
    constructor(public userName: string, todoItems: TodoItem[] = []) {
        todoItems.forEach(item => this.itemMap.set(item.id, item));
    }
 
    addTodo(task: string): number {
        while (this.getTodoById(this.nextId)) {
            this.nextId++;
        }        
        this.itemMap.set(this.nextId, new TodoItem(this.nextId, task));
        return this.nextId;
    }
 
    getTodoById(id: number) : TodoItem {
        return this.itemMap.get(id);
    }
 
    getTodoItems(includeComplete: boolean): TodoItem[] {
        return [...this.itemMap.values()]
            .filter(item => includeComplete || !item.complete);
    }
 
    markComplete(id: number, complete: boolean) {
        const todoItem = this.getTodoById(id);
        if (todoItem) {
            todoItem.complete = complete;
        }
    }    
}

In `src/todoCollection.ts`, `getTodoItems` expands the values of a `Map<number, TodoItem>` into an array, then filters that array according to `includeComplete`. The declared `TodoItem[]` return type and the map’s generic type let TypeScript check the items used by `filter`. section 2.2.6

How Essential TypeScript 5, Third Edition covers it

How deep it goes
Works through array and object expressions, property override order, and one typed collection method; does not develop a broader implementation model.
Examples
Shows product names and prices combined or passed to a function, object properties added or replaced, and to-do items filtered from a map.
What it assumes
Assumes familiarity with JavaScript arrays, functions, and object literals; introduces spread notation and demonstrates its use with typed map values.
What you can do after
Apply it via JavaScript and TypeScript syntax to expand arrays or object properties and convert typed map values for filtering.
How it connects
Connects spread to arrays, function arguments, object literals, rest syntax, Map, generics, and array filtering.

Also explained in

Compare how 3 books explain spread operator →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Essential TypeScript 5, Third Edition. The section links point to the parts of the book it draws on.