PROGRAMMING-CONCEPTS

Spread and Rest Operators: Definition, Purpose, and Examples

The spread and rest operators give developers flexible ways to expand or gather values from arrays, objects, and function arguments. Although they look identical (...) in JavaScript and TypeScript, their roles differ:

  • Spread expands a collection into individual elements
  • Rest collects multiple values into a single collection

Python offers similar behavior through unpacking with * and **, and Swift supports rest-like variadic parameters.

These features simplify data merging, configuration building, function signatures, and component logic across modern codebases.


What the Spread Operator Does

Spread expands an array, object, or iterable into separate elements. It helps create new collections without mutating existing ones.

Example: Expanding an array once

const numbers = [1, 2, 3];
const extended = [...numbers, 4, 5];

Spread makes the new array easier to read and avoids modifying numbers.

Example: Passing dynamic arguments

const nums = [4, 12, 8];
const max = Math.max(...nums);

Here, spread unpacks array values into function arguments.

Conditional spreading (real-world example)

This is common in configuration files:

const config = {
  mode: "production",
  ...(process.env.DEBUG && { debug: true })
};

If the condition is false, nothing is added.


What the Rest Operator Does

Rest collects multiple values into a single variable. You see it in function parameters and destructuring.

Collecting arguments in a function

function tag(label, ...items) {
  return `${label}: ${items.join(", ")}`;
}

tag("Fruits", "apple", "banana", "cherry");

items becomes an array containing all remaining arguments.

Array destructuring with rest

const [head, ...tail] = [10, 20, 30, 40];
// head = 10
// tail = [20, 30, 40]

Object rest

const user = { id: 7, name: "Luka", verified: true };
const { id, ...profile } = user;
// profile = { name: "Luka", verified: true }

Rest helps when you need part of an object but want to pass the remainder somewhere else.


Spread and Rest in TypeScript

TypeScript adds strong typing on top of JavaScript’s behavior.

Generic rest/spread merge utility

function mergeObjects<T extends object>(...objects: T[]): T {
  return Object.assign({}, ...objects);
}

const settings = mergeObjects(
  { theme: "dark" },
  { language: "en" },
  { notifications: true }
);

TypeScript ensures that all merged values match the expected object type.


Python’s Version: * and **

Python uses * for sequences and ** for dictionaries.

Expanding a list

a = [1, 2]
b = [*a, 3, 4]

Collecting arguments

def summarize(*values):
    return sum(values)

summarize(1, 5, 10)

Merging dictionaries

base = {"theme": "dark"}
overrides = {"language": "en"}

merged = {**base, **overrides}

The intent mirrors JavaScript spread/rest even though the symbols differ.


Swift’s Equivalent Features

Swift doesn’t use ... for collections, but supports rest-like parameters.

Variadic function example

func average(_ nums: Double...) -> Double {
    let total = nums.reduce(0, +)
    return total / Double(nums.count)
}

average(2.0, 4.0, 6.0)

For simple cases, tuple destructuring mimics unpacking behavior.


When Spread and Rest Are Most Useful

Spread/rest patterns shine when organizing code around flexible, composable data.

1. Updating or extending data immutably

Especially common in React state updates:

setSettings(prev => ({
  ...prev,
  theme: "light"
}));

Only the changed field is updated.

2. Merging configurations

Great for building API query parameters, command options, or UI settings.

const baseParams = { page: 1 };
const filters = { category: "books" };
const finalParams = { ...baseParams, ...filters };

3. Creating expressive function signatures

Rest parameters make your function handle unlimited arguments cleanly.

function combine(...sections) {
  return sections.join(" / ");
}

4. Transforming collections

Combined with destructuring, spread helps reorganize arrays:

const list = ["start", "middle", "end"];
const [, ...rest] = list; // ["middle", "end"]

Examples of Spread/Rest in Real Applications

Example 1: Building API query strings

const base = { limit: 20 };
const filters = { search: "python" };

const params = { ...base, ...filters };

This is standard in dashboards, admin panels, and data-driven apps.


Example 2: Immutable list insertion

const items = ["a", "b", "c"];
const updated = [...items.slice(0, 1), "x", ...items.slice(1)];

This pattern avoids mutating the original array.


Example 3: Normalizing event data

function logEvent(type, ...details) {
  console.log({ type, details });
}

logEvent("CLICK", "button", "header");

Rest makes the signature flexible.


Spread vs Rest: The Practical Rule

A simple way to remember the difference:

  • Spread “opens” a collection
  • Rest “gathers” values into a collection

Despite using the same symbol, they behave in opposite directions.


Common Mistakes and How to Avoid Them

Mistake: Confusing spread with deep clones

Spread only clones the first level:

const copy = { ...obj }; // nested objects still reference originals

Mistake: Order mismatch during object merging

Later spreads override earlier ones:

{ ...a, ...b } // b wins

Mistake: Using spread on non-iterables

Works only on arrays, iterables, and plain objects.

Mistake: Overusing nested spread

Deep or complicated spreads can reduce clarity.

Better to break it into steps for readability.


Summary

Spread expands values.

Rest collects values.

JavaScript and TypeScript use ..., Python uses * and **, and Swift supports rest-like variadic arguments. These operators simplify array manipulation, configuration merging, function design, React component patterns, and many real-world workflows. When used thoughtfully, spread and rest reduce duplication, improve readability, and make data structures far easier to work with.

Learn to Code for Free
Start learning now
button icon
To advance beyond this tutorial and learn to code by doing, try the interactive experience of Mimo. Whether you're starting from scratch or brushing up your coding skills, Mimo helps you take your coding journey above and beyond.

Sign up or download Mimo from the App Store or Google Play to enhance your programming skills and prepare for a career in tech.

Reach your coding goals faster