Mastering the Spread Operator in Node.js and TypeScript

This comprehensive guide delves into the spread operator, a powerful tool in JavaScript and TypeScript. It starts with an introduction to the spread operator, explaining its purpose and significance in modern programming. The guide then explores its usage in Node.js, showcasing practical examples of copying arrays, merging objects, and spreading function arguments. Moving on to TypeScript, it highlights how the spread operator enhances type safety and type inference, providing insights into common type errors and how to avoid them. The guide also covers potential pitfalls and common mistakes associated with the spread operator, such as mutating nested objects, performance issues with large arrays, and misuse in function arguments. It concludes with best practices for using the spread operator effectively, emphasizing the importance of understanding its limitations. This guide is designed to equip developers with a thorough understanding of the spread operator, enabling them to use it more effectively in their projects.

March 30, 2024 8 minute read

Thinh Dang

Experienced Fintech Software Engineer Driving High-Performance Solutions

  • Custom Social Profile Link

Introduction

The spread operator, denoted by ... , is an elegant syntax in JavaScript and TypeScript that enables the expansion of iterable elements such as arrays, or enumerable properties from objects into individual elements or properties. This operator is not only a syntactic convenience but also a means to promote immutability and functional programming patterns in modern development.

In Node.js, the spread operator proves to be invaluable when dealing with streams of data or when integrating middleware in frameworks like Express.js. It allows for seamless aggregation of data sources and the elegant application of functions over arrays of arguments.

TypeScript, being a superset of JavaScript, retains all the functionalities of the spread operator while enhancing type safety and predictability. When used in TypeScript, the spread operator helps maintain type definitions across spread elements, ensuring consistency and aiding in the development of robust applications.

The spread operator enhances code readability and maintainability, making it an indispensable tool in the modern developer’s toolkit.

Understanding the Spread Operator

The spread operator, denoted by ... , is a versatile addition to the JavaScript language that allows for more concise and readable code. It can be used with both arrays and objects to ‘spread’ or expand their elements or properties.

When applied to arrays, the spread operator can be used to clone arrays, merge arrays, and even insert elements at any position without mutating the original array.

Cloning Arrays

Cloning an array with the spread operator creates a shallow copy, meaning that the new array is a separate instance, but the elements are copied by reference if they are objects.

Merging Arrays

Merging arrays is straightforward with the spread operator. It allows the combination of multiple arrays into one.

Inserting Elements

Inserting elements into an array without altering the original can be done efficiently.

For objects, the spread operator can be used to copy properties from one object to another, creating a new object with combined properties.

Copying Objects

Copying an object is similar to cloning an array; it creates a shallow copy of the object.

Combining Objects

Combining properties from multiple objects into a single object is seamless with the spread operator.

Differences Between the Spread Operator and the concat() Method

While the spread operator and the concat() method can both be used to merge arrays, the spread operator offers more flexibility.

  • Immutability : The spread operator does not mutate the original arrays, whereas concat() can mutate the original if not used carefully.
  • Usage with Objects : The spread operator can be used with objects, while concat() is strictly for arrays.
  • Syntax : The spread operator provides a cleaner and more intuitive syntax, especially when dealing with complex operations.

In conclusion, the spread operator is a powerful feature in JavaScript that simplifies array and object manipulation, making code more maintainable and less prone to errors.

Usage in Node.js

The spread operator ( ... ) is a powerful feature in JavaScript, particularly in a Node.js environment, where it can be used to enhance the functionality and readability of your code. Below are some detailed use cases for the spread operator in Node.js.

Copying Arrays

When working with arrays, it’s often necessary to create a copy without altering the original array. The spread operator allows for shallow copying of array elements in a concise manner:

This method is beneficial when you need to ensure that the original array remains unchanged, especially when passing the array to functions that might otherwise modify it.

Merging Objects

In Node.js development, you might encounter situations where you need to combine properties from several objects into a single object. The spread operator makes this task straightforward:

This technique is particularly useful for options or settings objects where you might want to override default values with user-provided values.

Spreading Function Arguments

Functions in JavaScript can accept any number of arguments. The spread operator allows an array of values to be expanded into individual arguments in a function call:

This is particularly useful when the number of arguments is not known in advance or when applying an array of values to a function that expects separate arguments.

The spread operator is a versatile tool that simplifies array and object manipulations, making your Node.js code more efficient and maintainable.

Usage in TypeScript

The spread operator ( ... ) in TypeScript extends its functionality from JavaScript by enhancing type safety and type inference. This section delves into the specifics of how the spread operator can be utilized in TypeScript to maintain robust type adherence and facilitate accurate type deduction.

Type Safety

TypeScript’s robust type system leverages the spread operator to enforce type safety, effectively preventing type-related errors and safeguarding the integrity of your codebase. For instance:

In the above snippet, TypeScript ensures that both numbers and moreNumbers arrays are of type number[] , thereby averting inadvertent type inconsistencies.

Type Inference

The spread operator further contributes to type inference, where TypeScript deduces the type of the elements being spread based on the surrounding context. Observe the example below:

Here, TypeScript intelligently infers mixedArray as an array of type (number | string)[] , recognizing the amalgamation of number and string arrays.

Common Type Errors and Avoidance

Despite the spread operator’s contribution to type safety, developers must remain vigilant of potential type errors. Below are some typical errors and strategies to circumvent them:

  • Type Mismatch : It’s crucial to ensure compatibility between the type of the spread array and the target array or function parameters. For example:

To prevent such errors, verify that the types of the arrays being spread align with the intended target type.

Missing Type Annotations : Absent type annotations may lead TypeScript to misinterpret the type. In such scenarios, explicitly defining the type of the spread array can preclude errors.

Spread in Function Arguments : Discrepancies between the types of a spread array and the parameters of a function can lead to errors. For instance:

To avert such issues, confirm that the types of the spread array and the function’s parameters are congruent.

Adhering to these guidelines and best practices will enable you to harness the spread operator in TypeScript effectively, thereby enhancing both type safety and the clarity of your code.

Pitfalls and Common Mistakes

The spread operator ( ... ) is a versatile feature in JavaScript that allows for the expansion of iterable elements. Despite its convenience, improper use can lead to subtle bugs and inefficiencies. Below are some technical insights into common issues and how to avoid them.

Non-iterable Objects : The spread operator can only be used with iterable objects like arrays and strings. Attempting to spread a non-iterable object will result in a TypeError ¹.

Overwriting Properties : When spreading objects, if there are properties with the same name, the last one will overwrite the others. This might not be the intended behavior if you want to preserve all properties⁶.

Performance Issues : Using the spread operator in performance-critical loops or with large objects can negatively impact performance due to the creation of shallow copies³.

Deep Cloning : The spread operator performs a shallow copy, so nested objects are not deeply cloned. This can lead to unexpected behavior if the nested objects are modified².

Exceeding Argument Length : When using the spread operator for function calls, there’s a risk of exceeding the JavaScript engine’s argument length limit, which could cause a crash or an error¹.

Incorrect Constructor Calls : The spread operator cannot be directly used with the new operator in conjunction with apply() , as apply() calls the target function instead of constructing it¹.

Understanding these cases will help you avoid common pitfalls when using the spread operator in your JavaScript code.

You may also enjoy

typescript spread assignment

A Developer’s Guide to Implementing Python Observability in Microservices

June 30, 2024 18 minute read

This article serves as a comprehensive guide for developers on how to implement observability in microservices. It starts with an introduction to the concept...

typescript spread assignment

Setting Up Autoscaling with HPA and DataDog Metrics for a Python App in Kubernetes

June 18, 2024 18 minute read

This blog post provides a comprehensive guide on setting up Horizontal Pod Autoscaling (HPA) in a Kubernetes cluster using DataDog metrics for a Python appli...

typescript spread assignment

Navigating the Migration Landscape: An In-Depth Look at Flyway

May 23, 2024 11 minute read

This comprehensive guide explores the world of database migrations and introduces Flyway, a robust tool that simplifies the process. Learn why database migra...

typescript spread assignment

Efficient Database Migrations in Continuous Deployment with Flyway and Docker

May 20, 2024 16 minute read

This article provides a comprehensive guide on how to leverage Flyway and Docker for efficient database migrations in a continuous deployment environment. It...

The spread operator in TypeScript is a powerful feature that allows you to easily expand the contents of an array or object. This can come in handy when you need to make a copy of an existing object or array, or when you want to merge multiple array s or objects together.

What is the spread operator?

The spread operator (…) expands any iterable object into a list of arguments. This mainly means things like arrays and objects.

For example:

Here’s the result:

typescript spread assignment

In the first case, we get just the one array as an argument, but in the second case, each value in the array gets provided as an argument separately.

Why is this useful?

Firstly, this means that anywhere that is expecting a list of arguments and you have an array, you can use the spread operator to transform your array.

This is especially useful in TypeScript’s Math functions, which expect separate arguments rather than numbers:

Copying Objects/Arrays

If we take a look at the object {} and array [] syntax, these essentially accept a list of arguments as well. You might have created a new array by doing something like:

Which looks very similar to:

This means we can copy an object/array by turning it into a list of arguments, and then putting those arguments into a new object/array.

Here’s how you use the spread operator to clone an array:

The syntax is very similar for objects:

Shallow Clones

One important thing to note here is that we’re creating shallow copies. Let’s explore what that means through an example:

I’ve just created a simple object, and we’re cloning it with the spread operator. Now let’s perform some actions on it:

In the clone, Adam’s money is 200, just because that’s what we’ve set it to last. So what should Adam’s money be set to in the original, 10, 100 or 200? You might expect the original should still be 10, since we cloned the array, but let’s have a look:

typescript spread assignment

Why has Adam changed, even though we’ve cloned the object? This is because we’ve created a shallow clone. usersObject and newUsersObject refer to two different objects, but every object in them still refers to the same object. usersObject.adam is the same object as newUsersObject.adam.

In the first operation, this means we’re modifying the same object. In the second operation, since we’re actually changing what newUsersObject.adam refers to, nothing happens with the original.

Merging Objects/Arrays

You can also use the spread operator to merge two objects/arrays together. The syntax is essentially identical to cloning.

For arrays:

For objects:

Adding to objects/arrays

Adding an item to an object/array looks very similar to cloning.

You can add an item anywhere around the array, and you can add any number of items.

It works very similarly for objects:

For cloning, adding items, merging, etc, you might wonder why you would use the spread operator over solutions like .push(), or just setting a property. The main benefit in a lot of cases is mutability.

In a lot of cases, such as when building apps with React, you may not want to modify the original array/object directly. In some cases this is fine, concat() for example does not modify the original array, but in other cases such as when pushing and popping from an array, these will modify it, whereas using spread will give you a new array.

That’s all! Thanks for reading this article, hopefully, you now understand how and when to use the spread operator in TypeScript. If you liked this article, feel free to leave a comment below!

Related Posts:

  • Map Your Way to Cleaner Code With The Map Function…
  • Mastering TypeScript's New "satisfies" Operator
  • What Does The Finalize Operator Do In Angular/RxJS
  • Mastering the Builder Pattern in TypeScript
  • Mastering Typing React Props with TypeScript
  • Mastering Vue.js Directives: A Comprehensive Guide

Avatar photo

👋 Hey, I'm Omari Thompson-Edwards

💬 leave a comment cancel reply.

Your email address will not be published. Required fields are marked *

Upmostly brings you original JavaScript framework tutorials every week.

  • Cheatsheets
  • Write For Us

Copyright © 2024 Upmostly

HowToDoInJava

TypeScript / JavaScript Spread Operator

The spread operator is a new addition to the features available in the JavaScript ES6 version. The spread operator is used to expand or spread an iterable or an array in Typescript or Javascript. 1. When to use the Spread Operator? The spread operator (in the form of …

Lokesh Gupta

July 3, 2023

angular-typescript

The spread operator is a new addition to the features available in the JavaScript ES6 version. The spread operator is used to expand or spread an iterable or an array in Typescript or Javascript.

1. When to use the Spread Operator?

The spread operator (in the form of ellipsis ) can be used in two ways:

  • Initializing arrays and objects from another array or object
  • Object de-structuring

The spread operator is most widely used for method arguments in the form of rest parameters where more than 1 value is expected. A typical example can be a custom sum(...args) method which can accept any number of method arguments and add them to produce the sum.

2. Spread Operator Example

Let us check out a few examples of the spread operator to understand its usage better.

2.1. Initialize a New Array from Another Array

We can use the spread operator to create arrays from existing arrays in the given fashion.

2.2. Initialize a New Object from Another Object

We can also use the spread operator to create objects from the existing objects in the given fashion.

2.3. Object Destructuring

The destructuring assignment syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables.

3. Difference between Spread Operator and apply() Method

The JavaScript’s apply() method calls a function with a given this value, and arguments provided as an array . For example, in the below example, both highlighted function calls are equivalent. They both print the same output.

The Spread operator (part of ECMAScript 6) is a better version of the apply() method. Using the spread operator, we can write the above statement as given below.

Happy Learning !!

Ref: Mozilla Docs

Weekly Newsletter

Stay Up-to-Date with Our Weekly Updates. Right into Your Inbox.

Photo of author

TypeScript Logical Operators

Equals operator ( == ) vs strict equals operator ( === ).

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.

Tutorial Series

Privacy Policy

REST API Tutorial

logo

  • Web Application
  • My Portfolio

book

The Most Useful GIT Commands

Get a FREE cheat sheet ( value of 8.99$ ) with the most useful GIT commands.

How To Use The Spread Operator In TypeScript?

Tim Mouskhelichvili

You may have seen a mysterious syntax of three dots when you open a TypeScript file in your day-to-day coding life. This syntax is called the spread operator.

The spread operator allows to spread or expand iterable objects into individual elements.

This article explains the  spread operator in TypeScript and shows many code examples.

Let's get to it 😎.

typescript spread operator

  • The definition
  • Using the spread operator with an array
  • Using the spread operator with an object
  • Using the spread operator with a function call
  • Final thoughts

The spread operator, added with ES6, allows to spread or expand iterable objects into individual elements. The syntax for this operator is three dots ( ... ), also called an ellipsis .

Using the spread operator, a developer can:

  • Copy an array /object (shallow copy).
  • Merge an array/ object .
  • Pass an array to a function call as individual parameters.

⚠️ The spread operator is not the same as the rest operator, even though they both use the same syntax of three dots ( ... ). The rest operator is the inverse of the spread operator. Instead of expanding iterable objects into individual elements, it compresses them into one.

A developer can use the spread operator to copy an array in TypeScript.

Here is an example:

As you can see, copy now contains all the elements from the array called numbers .

⚠️ However, be careful because the spread operator only does a shallow copy. It works fine if you copy primitives, but if you want to copy objects, I advise using a library that can deep-clone.

Also, using the spread operator, you can merge two arrays.

This method works well as an alternative to the Array.concat function or the Lodash merge function.

Also, you can use the spread operator to define a new object from an existing object.

In this example, we define a new object called copiedObject from the existing object called obj1 .

You can also merge multiple objects with the spread operator:

⚠️ Remember, the spread operator only does a shallow copy, so if you try to clone objects, it will cause bugs.

You can also utilize the spread operator to pass an array as individual parameters in a function call.

In this example, using the spread operator, the params array we pass to the add function spreads as individual parameters.

When spreading an array in a function call, you can get this error: "A spread argument must either have a tuple type or be passed to a rest parameter."

To fix this error, you need to:

  • Define the array type as a tuple .
  • Use const assertion on the array (like I did in the example).

As you can see, the spread operator is great when you need to copy an array into a new array, merge two arrays, or copy object properties into a new object.

But remember that the spread operator only works well on primitive values because it does a shallow copy. If you want to clone objects, you can use a library like  clone-deep to make it work.

typescript spread operator

Here are some other  TypeScript tutorials  for you to enjoy:

  • The double question mark operator in TypeScript
  • The exclamation mark operator in TypeScript

Marius Schulz

Object Rest and Spread in TypeScript

TypeScript 2.1 adds support for the Object Rest and Spread Properties proposal that is slated for standardization in ES2018. You can work with rest and spread properties in a type-safe manner and have the compiler downlevel both features all the way down to ES3.

# Object Rest Properties

Let's assume you have defined a simple object literal with three properties:

Using the ES2015 destructuring syntax, you can create several local variables that hold the values of the corresponding property. TypeScript will correctly infer the type of each variable:

That's all good and true, but nothing new so far. This is where object rest comes into play and enables another destructuring feature: In addition to extracting a set of properties you're interested in, you can collect all remaining properties in a rest element using the ... syntax:

TypeScript will determine the correct types for all resulting local variables. While the twitterHandle variable is a plain string, the rest variable is an object containing the remaining two properties which weren't destructured separately.

# Object Spread Properties

Let's assume you want to use the fetch() API to make an HTTP request. It accepts two parameters: a URL and an options object containing any custom settings that you want to apply to the request.

In your application, you might encapsulate the call to fetch() and provide default options and the possibility to override specific settings for a given request. These options objects can look like this:

Using object spread, you can merge both objects into a single new object that you can the pass to the fetch() method:

Object spread will create a new object, copy over all property values from defaultOptions , and then copy over all property values from requestOptions — in that order, from left to right. Here's the result:

Notice that the order of assignments matters! If a property appears in both objects, the later assignment wins. This is why defaultOptions is listed before requestOptions — if it was the other way around, there would be no way to override the defaults.

Of course, TypeScript understands this ordering. Therefore, if multiple spread objects define a property with the same key, the type of that property in the resulting object will be the type of the property of the last assignment because it overrides previously assigned values of that property:

In a nutshell: later assignments win.

# Making Shallow Copies of Objects

Object spread can be used to create a shallow copy of an object. Let's say you want to create a new todo item from an existing one by creating a new object and copying over all properties. With object spread, that's a one-liner:

And indeed, you get a new object with all property values copied:

You can now modify the text property without changing the original todo item:

However, the new todo item references the same tags array as the first one. No deep clone was made! Therefore, mutating the array will impact both todos:

If you want to create a deep clone of a serializable object, consider JSON.parse(JSON.stringify(obj)) or some other approach. Just like Object.assign() , object spread only copies over property values, which might lead to unintended behavior if a value is a reference to another object.

Note that none of the code snippets in this post contain any type annotations or other TypeScript-specific constructs. It's just plain JavaScript mixed with the proposed object rest syntax. Type inference for the win!

This article and 44 others are part of the TypeScript Evolution series. Have a look!

The Spread Operator and Objects

In this lesson, you will use the spread operator on an object.

Simple copy

  • Shallow copy
  • Copying and adding members
  • Copy with an override value
  • Spreading an object literal
  • Spreading an object from a class

You can spread an object similar to an array. Spreading an object is handy in a scenario where you need to create a clone for immutability purposes or if you are already using the function Object.assign .

The assign method is similar in functionality but uses a more verbose syntax. The syntax for the spread operator is identical to the spread for an array which means that it uses the three dots in front of the object instead of the array.

To create a clone, you need to define a variable, open a curly bracket, a spread operator, the variable to copy, and close the curly bracket. It copies all members and makes them float side by side with a comma. Indeed, this is just a visualization to help you illustrate that the curly brackets take the result and form a new object.

In the following code, line 2 is performing the object clone. Notice the curly brackets { and } and the use of the spread operator ... . The output is false because they are not the same object, they have a different reference in memory. Altering one will not change the other.

Get hands-on with 1200+ tech skills courses.

Master Spread Operator With TypeScript

Master Spread Operator With TypeScript

You probably know the spread operator. It’s those ... that you see when you open most of the JavaScript files? Yes, those ones.

The spread operator — spoiler alert — can spread the contents of an array or an object. It’s basically the opposite of destructuring.

In this article we will review how it works and I will give you some tips on where you can use it.

Butterkuchen? 🥮

Let’s have a quick look at how it works.

Consider the following arrays:

Typically, if you were about to concatenate them, you would use something like this:

You know where this is going…

With the spread operator we could have the same result:

In the example above, we concatenate the two arrays commercialGenres and classicalGenres , by creating a new array genres . We use the spread operator two times to spread out the values of the two arrays.

The sequence plays a big role here:

Note, that the values of classicalGenres are now first in this example.

We can use the spread operator to remove duplicate values from an array:

Photo Credit: Claudio Schwarz

Using with objects

The spread operator can also be used with JavaScript objects.

Redux has popularized the idea of storing the complete application state into a single JavaScript object. The spread operator shines when it comes to merging current and new states.

Consider the following example:

This function will basically merge the two objects, similar to how the method Array.prototype.concat() works for arrays.

We can now use the updateSettings() function by passing the current state of our settings object, followed by another object with the values we want to override:

The result will be the following:

Note that the values for updates and volume have been modified, but the other values have remained the same.

It’s important to mention here that this performs a shallow merge. That’s why the system object has only the volume and all the other properties have been removed. If you want to deeply merge the two objects, you have to repeat the process one more time.

By invoking our function with the same object as before, we will get back the full object for settings , with the update value for the volume :

Also worth noting that when we have a property with an object as a value, the spread operator copies its values. So, changes in the original object will not impact the newly created one.

Photo Credit: Karolína Maršálková

The rest operator

The spread operator has a very friendly sibling; the rest operator . Both of them share the three ... dots.

Here’s how we can use it:

This will basically store all the remaining items in a variable that we named rest .

You can freely choose the name that you like. Many developers prefer to use rest as a naming convention. According to Clean Code, it’s a good practice to name what this array is about, for example restDays , or restProps .

Where the rest operator shines is with function arguments:

The function receives an infinite number of strings. It returns the first two values, and displays the count of the remaining ones. Here we use the rest operator to store the remaining arguments in the otherArgs variable.

Cover photo credit: Alper Güzeler

  • Underscore.js
  • Tensorflow.js
  • JS Formatter
  • Web Technology

How to use Spread Operator in TypeScript ?

The spread operator in Typescript , denoted by three dots (`…`), is a powerful tool, that allows you to spread the elements of an array or objects into another array or objects. This operator makes it easy to copy arrays, combine arrays, or create shallow copies of iterable.

Example 1: Creating a Shallow Copy of an Array

The below code implements the spread operator to create a shallow copy of an array.

Example 2: Combining Elements of Two Arrays

The below code combines the elements of two different arrays into a single array using spread operator.

Example 3: Creating a Shallow Copy of an Object

The below code implements the spread operator to create a shallow copy of an object.

Example 4: Modifying a Property of an Object

The below code modifies the value of an property of an object using spread operator.

The spread operator in TypeScript simplifies array and object manipulation by enabling easy copying, combining, and property modification. Its concise syntax enhances code readability and efficiency, making it an essential tool for modern TypeScript development.

FAQs-Spread Operator in TypeScript

Can the spread operator be used to merge arrays in typescript.

Yes, the spread operator can combine arrays, e.g., […array1, …array2].

How do you copy an object using the spread operator in TypeScript?

Create a shallow copy of an object with { …originalObject }.

Is it possible to modify properties of an object using the spread operator?

Yes, you can modify properties by spreading the object and then specifying the new properties, e.g., { …originalObject, newProperty: value }.

What are the differences between the spread operator and the rest operator?

The spread operator expands elements, while the rest operator (…) collects multiple elements into an array.

Can you use the spread operator with nested objects or arrays in TypeScript?

The spread operator only creates shallow copies, so nested objects or arrays are still referenced.

How does the spread operator handle missing properties in objects?

Missing properties will not be included in the new object when using the spread operator.

author

Please Login to comment...

Similar reads.

  • Geeks Premier League
  • Web Technologies
  • Geeks Premier League 2023
  • How to Get a Free SSL Certificate
  • Best SSL Certificates Provider in India
  • Elon Musk's xAI releases Grok-2 AI assistant
  • What is OpenAI SearchGPT? How it works and How to Get it?
  • Content Improvement League 2024: From Good To A Great Article

Improve your Coding Skills with Practice

 alt=

What kind of Experience do you want to share?

  • Skip to main content
  • Skip to search
  • Skip to select language
  • Sign up for free
  • Português (do Brasil)

Spread syntax (...)

The spread ( ... ) syntax allows an iterable, such as an array or string, to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected. In an object literal, the spread syntax enumerates the properties of an object and adds the key-value pairs to the object being created.

Spread syntax looks exactly like rest syntax. In a way, spread syntax is the opposite of rest syntax. Spread syntax "expands" an array into its elements, while rest syntax collects multiple elements and "condenses" them into a single element. See rest parameters and rest property .

Description

Spread syntax can be used when all elements from an object or array need to be included in a new array or object, or should be applied one-by-one in a function call's arguments list. There are three distinct places that accept the spread syntax:

  • Function arguments list ( myFunction(a, ...iterableObj, b) )
  • Array literals ( [1, ...iterableObj, '4', 'five', 6] )
  • Object literals ( { ...obj, key: 'value' } )

Although the syntax looks the same, they come with slightly different semantics.

Only iterable values, like Array and String , can be spread in array literals and argument lists. Many objects are not iterable, including all plain objects that lack a Symbol.iterator method:

On the other hand, spreading in object literals enumerates the own properties of the value. For typical arrays, all indices are enumerable own properties, so arrays can be spread into objects.

All primitives can be spread in objects. Only strings have enumerable own properties, and spreading anything else doesn't create properties on the new object.

When using spread syntax for function calls, be aware of the possibility of exceeding the JavaScript engine's argument length limit. See Function.prototype.apply() for more details.

Spread in function calls

Replace apply().

It is common to use Function.prototype.apply() in cases where you want to use the elements of an array as arguments to a function.

With spread syntax the above can be written as:

Any argument in the argument list can use spread syntax, and the spread syntax can be used multiple times.

Apply for new operator

When calling a constructor with new , it's not possible to directly use an array and apply() , because apply() calls the target function instead of constructing it, which means, among other things, that new.target will be undefined . However, an array can be easily used with new thanks to spread syntax:

Spread in array literals

A more powerful array literal.

Without spread syntax, the array literal syntax is no longer sufficient to create a new array using an existing array as one part of it. Instead, imperative code must be used using a combination of methods, including push() , splice() , concat() , etc. With spread syntax, this becomes much more succinct:

Just like spread for argument lists, ... can be used anywhere in the array literal, and may be used more than once.

Copying an array

You can use spread syntax to make a shallow copy of an array. Each array element retains its identity without getting copied.

Spread syntax effectively goes one level deep while copying an array. Therefore, it may be unsuitable for copying multidimensional arrays. The same is true with Object.assign() — no native operation in JavaScript does a deep clone. The web API method structuredClone() allows deep copying values of certain supported types . See shallow copy for more details.

A better way to concatenate arrays

Array.prototype.concat() is often used to concatenate an array to the end of an existing array. Without spread syntax, this is done as:

With spread syntax this becomes:

Array.prototype.unshift() is often used to insert an array of values at the start of an existing array. Without spread syntax, this is done as:

With spread syntax, this becomes:

Note: Unlike unshift() , this creates a new arr1 , instead of modifying the original arr1 array in-place.

Conditionally adding values to an array

You can make an element present or absent in an array literal, depending on a condition, using a conditional operator .

When the condition is false , we spread an empty array, so that nothing gets added to the final array. Note that this is different from the following:

In this case, an extra undefined element is added when isSummer is false , and this element will be visited by methods such as Array.prototype.map() .

Spread in object literals

Copying and merging objects.

You can use spread syntax to merge multiple objects into one new object.

A single spread creates a shallow copy of the original object (but without non-enumerable properties and without copying the prototype), similar to copying an array .

Overriding properties

When one object is spread into another object, or when multiple objects are spread into one object, and properties with identical names are encountered, the property takes the last value assigned while remaining in the position it was originally set.

Conditionally adding properties to an object

You can make an element present or absent in an object literal, depending on a condition, using a conditional operator .

The case where the condition is false is an empty object, so that nothing gets spread into the final object. Note that this is different from the following:

In this case, the watermelon property is always present and will be visited by methods such as Object.keys() .

Because primitives can be spread into objects as well, and from the observation that all falsy values do not have enumerable properties, you can simply use a logical AND operator:

In this case, if isSummer is any falsy value, no property will be created on the fruits object.

Comparing with Object.assign()

Note that Object.assign() can be used to mutate an object, whereas spread syntax can't.

In addition, Object.assign() triggers setters on the target object, whereas spread syntax does not.

You cannot naively re-implement the Object.assign() function through a single spreading:

In the above example, the spread syntax does not work as one might expect: it spreads an array of arguments into the object literal, due to the rest parameter. Here is an implementation of merge using the spread syntax, whose behavior is similar to Object.assign() , except that it doesn't trigger setters, nor mutates any object:

Specifications

Specification

Browser compatibility

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

  • Rest parameters
  • Rest property
  • Function.prototype.apply()

javascript typescript spread operator

6 Awesome Tricks with the Spread and Rest Operators in Typescript and Javascript Objects

Table of Contents

Introduction

You may have seen this syntax in Typescript and Javascript Projects before:

if you have used React , then you have very likely encountered this syntax a couple of times when passing the props from one component to another.

The support for the spread and rest operators was added since:

Typescript 2.1 and onwards

Javascript with ES6 specifications and onwards

As you are reading this article, the support for those operators has been there for a very long time, and whatever environment you’re using pretty much supports it now.

The spread and rest operators have a number of uses that can make manipulating an object a joy, and here are 6 ways to do so!

1 Clone an Object with Spread Operator

There will be times when you want to modify an object, but without losing the original object data.

The problem

referenced image

Doing this will only create a reference of our cat object, meaning they are one and the same in memory. Modifying either of them will update the same memory allocation.

What if we wanted to modify anotherCat without cat being affected?

Spread operator to the rescue!

with the spread operator, we can quickly create a clone of our object!

spread operator, different result

2 Extract Values from an object

This one isn’t directly about the spread and rest operators, but it will build the knowledge required for our next point!

We can extract specific properties from our object by doing so:

typescript spread assignment

what you have to take note of when extracting properties is we are creating new instances for everything. This means if we modify cat after extracting its properties, then the changes won’t be reflected in the extracted properties.

typescript spread assignment

So, if we wanted to have this change apply to our extracted properties, we have to apply them before extracting the properties like so:

typescript spread assignment

3 Exclude Values from an object with Rest Operator

This is a cool one. What if we wanted to remove some of the properties?

this is where the reset operator comes in

the rest operator here means “combine the rest of the properties in a new object”. and it will give us this result:

typescript spread assignment

and just like extracting properties, modifying cat properties will not update the values for newCat , as it is a completely new object:

Spread Operator vs Rest Operator in Typescript and Javascript

The spread operator.

The spread operator is found on the right-hand side of the object assignment.

It spreads the object keys in the sense that it iterates over each property:

This is what we are doing if we wanted to look at it in a “literal” sense:

now It makes more sense how the spread operator is creating a new instance of the object.

The Rest Operator

The rest operator is found on the left-hand side of the object assignment.

with the rest operator, we are doing the opposite. we are collecting all of the properties in a single object.

now if we wanted to combine the remaining name and color properties, then we will use the rest operator like in our previous example .

and a “literal” sense, this is what we are doing:

So from those examples, I believe you can understand that we are using the spread and rest operators to clone properties and their values from an existing object, rather than writing them down manually.

Okay, but what happens if we use the rest operator without extracting any properties?

Bonus: Another way to clone an object

Now that we are aware of what the rest operator is doing, we can also come to this conclusion:

typescript spread assignment

Both syntaxes work to achieve the same goal to clone an object

4 Combine objects with Spread Operator

let us say that we have an object that we want to change some of its properties, we can use the spread operator to do so:

typescript spread assignment

as you can see, we have changed the name , type , and age properties of the cat object with the ones that were provided by anotherCat .

A few things to know:

  • Once again, we are creating a new object, and not referencing either of the original objects.
  • The last object’s values are the ones that will be put in the combined object.

Combine Multiple Objects

To elaborate more on the second point, this means that if we were to have a third object in there, then its values are the ones that will apply in the combined object.

typescript spread assignment

Think of it like this:

anotherCat values will be applied on top of cat

then, thirdCat values will be applied on top of the modified cat

Combine objects with different properties

combining with the spread operator does not restrict us to having the exact same properties of the first object.

typescript spread assignment

this way, the properties that didn’t exist with cat will be added in the combinedCat object!

5 Change Multiple Properties

typescript spread assignment

we can also combine this with our previous example!

typescript spread assignment

6 Add new properties to an object with Spread Operator

If we wanted to add a property that didn’t exist in the object before:

Then we will get the following error:

to work around this issue, we can use the spread operator to create a new object with the new property!

typescript spread assignment

To really understand this in Typescript , if we were to make an interface, we can see that the new object generated by the spread operator does NOT have the original interface:

this means we are creating a new object without the constraints of our Cat interface.

so if we wanted to retain the type safety of our cloned object, then we will need to explicitly say that it is of type Cat .

and if we really wanted everything to have a proper interface for it, then we can do something like this:

Bonus: everything together!

Let us recap by using everything we just learned!

this is a more advanced example where we’ll be using multiple things together:

before you have a look at the output, I’d want you to have a moment to think about what the result of newCat and combinedCat will be. See if you can get it right.

typescript spread assignment

The spread and rest operators are very powerful tools to manipulate objects. You will very likely be using it in your Typescript and Javascript apps. So make sure you get comfortable with it! You will likely use them very often in your react and express apps.

Sing up to get an email notification when new content is published

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Save my name, email, and website in this browser for the next time I comment.

Similar Posts

Sorting An Array of Strings in Typescript and Javascript

Sorting An Array of Strings in Typescript and Javascript

Earlier, we learned how to filter an array in Typescript/Javascript. and now, we will have a quick look over Array.sort() in typescript and javascript. While what we will learn here is simple, it will be the foundation we need for our coming tutorials! Sorting Strings in Javascript / Typescript So we’d have this array: Javascript…

Why Tsup Beats Nodemon and Ts-Node for Path Alias in TypeScript

Why Tsup Beats Nodemon and Ts-Node for Path Alias in TypeScript

Introduction To answer the title’s questions, it’s because no extra configuration is required for tsup! I have previously talked about how we can get a typescript projected started with tsup, typescript and express. I have also mentioned that we did not configure tsconfig.json, so let us tackle this part with path aliases! Note that for…

How to filter an array of objects in Typescript, the easy way

How to filter an array of objects in Typescript, the easy way

Filtering is something that you would often do in your Javascript and Typescript applications. We’ll be using Array.filter() to achieve this and to make the information more digestible, we will start with a simple array. Filtering an Array of Numbers so let us say we have an array of numbers and we want to filter…

How To Extend Express Request Interface in Typescript

How To Extend Express Request Interface in Typescript

The problem You will likely be caught in this situation when you create middleware that processes the request data before it reaches the resource route. An example of this is JWT, where you will need to decode the token before every request, and put in the decoded data somewhere. In Javascript, it would have been…

How to configure and resolve path alias with a Typescript Project

How to configure and resolve path alias with a Typescript Project

What is a path alias? Path alias is a way to define an absolute path in your typescript project with a word, path or a character. a very common syntax you will see is replacing the src directory with @ The advantage of using a path alias is that you no longer need to use…

How to resolve a path alias in Storybook

How to resolve a path alias in Storybook

We have solved the path alias issue with CRA projects earlier, but we are likely going to encounter it again if we are Storybook. This tutorial will give us a really simple solution to the problem with a few modifications to Storybook’s webpack.

  • What is a merge queue
  • Defining merge skew

Guides by topic

  • stacked diffs
  • code review
  • phabricator
  • repo configuration
  • GitHub Actions
  • GitHub Copilot

Operators in TypeScript

Kenny DuMez

TypeScript, a superset of JavaScript, introduces several enhancements to the language, including additional operators and improved type checking. This guide will cover the fundamental and advanced operators in TypeScript, providing a clear understanding of their syntax and practical usage. We'll explore various operators such as the ternary operator, spread operator, and more.

  • Arithmetic operators

TypeScript supports standard arithmetic operators such as addition ( + ), subtraction ( - ), multiplication ( * ), and division ( / ). These operators work similarly to other C-like languages, allowing you to perform mathematical calculations.

  • Assignment operators

Assignment operators in TypeScript are used to assign values to variables. The most basic operator is the simple assignment operator ( = ), which assigns the right-hand operand to the left-hand operand. Other compound operators, like += , -= , *= , and /= , perform an operation and assignment in one step.

  • Comparison operators

Comparison operators compare two values and return a Boolean value, true or false. These include:

  • == (equality)
  • === (strict equality)
  • != (inequality)
  • !== (strict inequality)
  • > (greater than)
  • < (less than)
  • >= (greater than or equal to)
  • <= (less than or equal to)

In TypeScript, as in JavaScript, the == , and === operators, along with their negative counterparts != , and !== , are used for comparing values, but they differ significantly in how they handle type coercion:

== (equality operator): This operator tests for abstract equality. It converts both operands to a common type before making the comparison. For example, if you compare a number with a string, the string is converted to a number before the comparison is made. This can lead to somewhat unexpected results where "2" == 2 evaluates to true .

=== (strict equality operator): This operator tests for strict equality, meaning that it does not perform type conversion. If the values being compared have different types, the comparison will immediately return false . For example, "2" === 2 would evaluate to false because one is a string and the other is a number. This operator is generally recommended for use over == in TypeScript (and JavaScript) to avoid errors related to type coercion.

=== and !=== check both value and type, which leads to more predictable and safer code, whereas == and !== only check the value after performing type coercion, which can introduce subtle bugs.

  • Logical operators

Logical operators are used to determine the logic between variables or values:

  • && (logical and)
  • || (logical or)
  • ! (logical not)

The logical operators && , || , and ! are used to combine or invert boolean values. The && operator (logical AND) returns true only if both operands are true; in the example, condition1 && condition2 returns false because condition2 is false. The || operator (logical OR) returns true if at least one of the operands is true, which is why condition1 || condition2 evaluates to true , and the ! operator (logical NOT) inverses the boolean value of its operand, making !condition1 return false since condition1 is true.

  • Ternary operator (conditional operator)

The ternary operator <condition> ? <output> : <output> in TypeScript is a shorthand for the if-else statement, which is used to assign a value to a variable based on some specified condition.

This can be interpreted as if age is greater than or equal to 18 return Yes else return No .

  • Spread operator

The spread operator ( ... ) allows an iterable such as an array or string to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected.

in operator

The in operator returns true if the specified property is contained in the specified object or its prototype chain.

  • TypeScript's type-specific operators

The question mark operator ( ? )

In TypeScript, the question mark is used in two contexts. First, it can be used to denote optional properties in interfaces or objects. Second, it serves as a part of the optional chaining operator ( ?. ), which allows you to safely access deeply nested properties.

For further reading on TypeScript operators, see the official TypeScript documentation .

Gerrit vs. Phabricator: Key Differences

Gerrit and Phabricator cater to different needs within the software development lifecycle. Gerrit is...

5 problems stacked diffs address

Stacked diffs represent a strategic shift towards modular, efficient, and quality-centric developmen...

Smartlog is a central feature in Sapling, designed to offer users a more digestible view of their lo...

Last modified 3 months ago

  • `in` operator

Give your PR workflow an upgrade today

Stack easier | Ship smaller | Review quicker

Product Screenshot 1

typescript spread assignment

Destructuring

TypeScript supports the following forms of Destructuring (literally named after de-structuring i.e. breaking up the structure):

Object Destructuring

Array destructuring.

It is easy to think of destructuring as an inverse of structuring . The method of structuring in JavaScript is the object literal:

Without the awesome structuring support built into JavaScript, creating new objects on the fly would indeed be very cumbersome. Destructuring brings the same level of convenience to getting data out of a structure.

Destructuring is useful because it allows you to do in a single line, what would otherwise require multiple lines. Consider the following case:

Here in the absence of destructuring you would have to pick off x,y,width,height one by one from rect .

To assign an extracted variable to a new variable name you can do the following:

Additionally you can get deep data out of a structure using destructuring. This is shown in the following example:

Object Destructuring with rest

You can pick up any number of elements from an object and get an object of the remaining elements using object destructuring with rest.

A common use case is also to ignore certain properties. For example:

A common programming question: "How to swap two variables without using a third one?". The TypeScript solution:

Note that array destructuring is effectively the compiler doing the [0], [1], ... and so on for you. There is no guarantee that these values will exist.

Array Destructuring with rest

You can pick up any number of elements from an array and get an array of the remaining elements using array destructuring with rest.

Array Destructuring with ignores

You can ignore any index by simply leaving its location empty i.e. , , in the left hand side of the assignment. For example:

JS Generation

The JavaScript generation for non ES6 targets simply involves creating temporary variables, just like you would have to do yourself without native language support for destructuring e.g.

Destructuring can make your code more readable and maintainable by reducing the line count and making the intent clear. Array destructuring can allow you to use arrays as though they were tuples.

Last updated 4 years ago

typescript spread assignment

  • Tips & How-To
  • Newsletters
  • White Papers
  • .NET Tips and Tricks
  • The Data Science Lab
  • Practical .NET

The Practical Client

  • Data Driver
  • PDF Back Issues
  • HTML Issue Archive
  • Code Samples
  • Agile/Scrum
  • Open Source
  • Cross-Platform C#
  • Mobile Corner
  • Live! Video

typescript spread assignment

  • Visual Studio
  • Visual Studio Code
  • Blazor/ASP.NET
  • C#/VB/TypeScript
  • Xamarin/Mobile
  • AI/Machine Learning

typescript spread assignment

Copying Classes in TypeScript

If you need to create a version of a class from several sources or just want to merge default values with a user's input, object spreading solves your problem. JavaScript won't let you do this (yet) but TypeScript will.

  • By Peter Vogel

typescript spread assignment

One of the attractive features of TypeScript is how it incorporates features that aren't (yet) available in JavaScript. The object spread syntax that allows you to merge multiple objects into a single new class is a good example. Having access to the syntax is useful because it simplifies a common problem down to a single line of code.

First, some background: TypeScript uses a kind of duck typing that considers two objects to be "the same type" if they have matching properties. Here, as an example, is a CustomerClass (with two properties) and a CreditCustomer class (with two identical properties plus one more):

Thanks to the way TypeScript considers classes to be compatible, this code works:

TypeScript considers the classes to be compatible because CreditCustomer has all the properties that Customer has. As a result, as my code shows, I can assign a CreditCustomer object to a Customer variable.

typescript spread assignment

For example, I can define a class called creditValue that has a single property called creditLimit:

I can then instantiate it and set its creditLimit property:

Finally, using the object spread syntax, I can use my original Customer object and my new creditValue object as input to create a new CreditCustomer object with all of its properties set (the ellipsis in this syntax gathers up all properties not explicitly referenced):

The new CreditCustomer object object in the ccust variable will have its firstName and lastName properties set from the cust variable and its creditLimit property set from the cv variable.

However, that's a lot of work just to set a single property. Fortunately, the object spread syntax also lets me use a property assignment expression as one of the inputs. That means I can also set the creditLimit value with code like this:

Adding Flexibility You're not limited to providing just two objects -- you can pull your values from as many inputs as you want. If a property name is repeated in multiple inputs, the later input's values win. This code, for example, uses three inputs, seting the cust variable's firstName to Jason in the last item:

With this code, The firstName property on the ccust variable will be set to Jason regardless of what value the firstName property may have in scust. However, properties that have no values in later items will have no effect on properties in earlier items (I'll take advantage of this later to use object spread to combine user inputs with default values).

TypeScript, being type safe, will prevent you from assigning values to properties that don't exist on the target class (JavaScript does not). This code won't work, for example, because CreditCustomer doesn't have a property called totalSales:

By the way (and if you care about the resulting JavaScript code), under the hood TypeScript is using its __assign helper to implement this functionality.

Exploiting Object Spread That's all very interesting but you have to ask if it's useful.

One place you can use the object spread syntax to create a new copy of an object from an existing object. To create a new Customer from an existing Customer I can use code like this, providing just one item:

This gives me a whole new Customer object in cust2 which I can update without disturbing the values in the original cust object.

However, the object spread syntax just gives you a shallow copy of the Customer object. That will work fine for my simple Customer class but probably won't give you what you want with a class that holds anything other than a scalar value in its properties. For example, let's say my Customer object has a homeAddress property that holds an Address class:

If I use object spread to copy this object, the Address object in homeAddress will be copied to the cust2 object. However, I won't get a new copy of the Address object -- only the reference to the Address object will be copied. As a result, any changes I make to the homeAddress property either through the cust or cust2 variables will show up in both places.

More usefully, I can use object spread to override values in some default object with a set of specified values. This code, for example, combines a defaultValues object with a userInput object to create a parm object. That parm object is then passed as a parameter to a method:

Because the userInput object never has its url property set, parm will still have the original value from defaultValues in its url property. On the other hand, because userInput has its data property set, parm will have its data property set to A123.

Thanks to TypeScript you can start using the object spread syntax now while ensuring type safety: the best of both the JavaScript and the data-typed world in one bundle.

About the Author

Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter tweets about his VSM columns with the hashtag #vogelarticles. His blog posts on user experience design can be found at http://blog.learningtree.com/tag/ui/ .

Printable Format

typescript spread assignment

The Well-Architected Architect on Azure

In the dynamic field of cloud computing, the architect's role is increasingly pivotal as they must navigate a complex landscape, considering everything from the overarching architecture and individual service configurations to the various trade-offs involved. Here's help.

typescript spread assignment

Windows Community Toolkit Update Improves Controls

The Windows Community Toolkit advanced to version 8.1, adding new features, improving existing controls and making dependency changes.

typescript spread assignment

ASP.NET Core, .NET MAUI Updated as .NET 9 Nears

The web-dev ASP.NET Core framework and Xamarin.Forms' successor .NET MAUI received the lion's share of dev attention in the seventh preview of .NET 9 as Microsoft preps for a November launch at .NET Conf 2024.

typescript spread assignment

.NET Community Toolkit Gets Native AOT and .NET 8 Support

The .NET Community Toolkit is Microsoft's latest dev tooling to get native ahead-of-time compilation, continuing a years-long push for that capability across the board.

typescript spread assignment

GitHub Copilot Tops Research Report on AI Code Assistants

GitHub topped research firm's Gartner's inaugural Magic Quadrant report on AI code assistants, with Copilot leading in both completeness of vision and ability to execute.

  • Most Popular Articles
  • Most Emailed Articles

typescript spread assignment

Subscribe on YouTube

Visual Studio Magazine Readers Choice Awards

Upcoming Training Events

typescript spread assignment

Free Webcasts

  • Myths and Realities in Telemetry Data Handling
  • How .NET MAUI Changes the Cross-Platform Game Summit
  • MoneyTree Achieves Compliance and Speeds Innovation with AWS and Sumo Logic
  • Best Practices for AWS Monitoring

> More Webcasts

typescript spread assignment

Was this page helpful?

Type Compatibility

Type compatibility in TypeScript is based on structural subtyping. Structural typing is a way of relating types based solely on their members. This is in contrast with nominal typing. Consider the following code:

In nominally-typed languages like C# or Java, the equivalent code would be an error because the Dog class does not explicitly describe itself as being an implementer of the Pet interface.

TypeScript’s structural type system was designed based on how JavaScript code is typically written. Because JavaScript widely uses anonymous objects like function expressions and object literals, it’s much more natural to represent the kinds of relationships found in JavaScript libraries with a structural type system instead of a nominal one.

A Note on Soundness

TypeScript’s type system allows certain operations that can’t be known at compile-time to be safe. When a type system has this property, it is said to not be “sound”. The places where TypeScript allows unsound behavior were carefully considered, and throughout this document we’ll explain where these happen and the motivating scenarios behind them.

Starting out

The basic rule for TypeScript’s structural type system is that x is compatible with y if y has at least the same members as x . For example consider the following code involving an interface named Pet which has a name property:

To check whether dog can be assigned to pet , the compiler checks each property of pet to find a corresponding compatible property in dog . In this case, dog must have a member called name that is a string. It does, so the assignment is allowed.

The same rule for assignment is used when checking function call arguments:

Note that dog has an extra owner property, but this does not create an error. Only members of the target type ( Pet in this case) are considered when checking for compatibility. This comparison process proceeds recursively, exploring the type of each member and sub-member.

Be aware, however, that object literals may only specify known properties . For example, because we have explicitly specified that dog is of type Pet , the following code is invalid:

Comparing two functions

While comparing primitive types and object types is relatively straightforward, the question of what kinds of functions should be considered compatible is a bit more involved. Let’s start with a basic example of two functions that differ only in their parameter lists:

To check if x is assignable to y , we first look at the parameter list. Each parameter in x must have a corresponding parameter in y with a compatible type. Note that the names of the parameters are not considered, only their types. In this case, every parameter of x has a corresponding compatible parameter in y , so the assignment is allowed.

The second assignment is an error, because y has a required second parameter that x does not have, so the assignment is disallowed.

You may be wondering why we allow ‘discarding’ parameters like in the example y = x . The reason for this assignment to be allowed is that ignoring extra function parameters is actually quite common in JavaScript. For example, Array#forEach provides three parameters to the callback function: the array element, its index, and the containing array. Nevertheless, it’s very useful to provide a callback that only uses the first parameter:

Now let’s look at how return types are treated, using two functions that differ only by their return type:

The type system enforces that the source function’s return type be a subtype of the target type’s return type.

Function Parameter Bivariance

When comparing the types of function parameters, assignment succeeds if either the source parameter is assignable to the target parameter, or vice versa. This is unsound because a caller might end up being given a function that takes a more specialized type, but invokes the function with a less specialized type. In practice, this sort of error is rare, and allowing this enables many common JavaScript patterns. A brief example:

You can have TypeScript raise errors when this happens via the compiler flag strictFunctionTypes .

Optional Parameters and Rest Parameters

When comparing functions for compatibility, optional and required parameters are interchangeable. Extra optional parameters of the source type are not an error, and optional parameters of the target type without corresponding parameters in the source type are not an error.

When a function has a rest parameter, it is treated as if it were an infinite series of optional parameters.

This is unsound from a type system perspective, but from a runtime point of view the idea of an optional parameter is generally not well-enforced since passing undefined in that position is equivalent for most functions.

The motivating example is the common pattern of a function that takes a callback and invokes it with some predictable (to the programmer) but unknown (to the type system) number of arguments:

Functions with overloads

When a function has overloads, each overload in the target type must be matched by a compatible signature on the source type. This ensures that the source function can be called in all the same cases as the target function.

Enums are compatible with numbers, and numbers are compatible with enums. Enum values from different enum types are considered incompatible. For example,

Classes work similarly to object literal types and interfaces with one exception: they have both a static and an instance type. When comparing two objects of a class type, only members of the instance are compared. Static members and constructors do not affect compatibility.

Private and protected members in classes

Private and protected members in a class affect their compatibility. When an instance of a class is checked for compatibility, if the target type contains a private member, then the source type must also contain a private member that originated from the same class. Likewise, the same applies for an instance with a protected member. This allows a class to be assignment compatible with its super class, but not with classes from a different inheritance hierarchy which otherwise have the same shape.

Because TypeScript is a structural type system, type parameters only affect the resulting type when consumed as part of the type of a member. For example,

In the above, x and y are compatible because their structures do not use the type argument in a differentiating way. Changing this example by adding a member to Empty<T> shows how this works:

In this way, a generic type that has its type arguments specified acts just like a non-generic type.

For generic types that do not have their type arguments specified, compatibility is checked by specifying any in place of all unspecified type arguments. The resulting types are then checked for compatibility, just as in the non-generic case.

For example,

Advanced Topics

Subtype vs assignment.

So far, we’ve used “compatible”, which is not a term defined in the language spec. In TypeScript, there are two kinds of compatibility: subtype and assignment. These differ only in that assignment extends subtype compatibility with rules to allow assignment to and from any , and to and from enum with corresponding numeric values.

Different places in the language use one of the two compatibility mechanisms, depending on the situation. For practical purposes, type compatibility is dictated by assignment compatibility, even in the cases of the implements and extends clauses.

any , unknown , object , void , undefined , null , and never assignability

The following table summarizes assignability between some abstract types. Rows indicate what each is assignable to, columns indicate what is assignable to them. A ” ✓ ” indicates a combination that is compatible only when strictNullChecks is off.

any unknown object void undefined null never
any →
unknown →
object →
void →
undefined →
null →
never →

Reiterating The Basics :

  • Everything is assignable to itself.
  • any and unknown are the same in terms of what is assignable to them, different in that unknown is not assignable to anything except any .
  • unknown and never are like inverses of each other. Everything is assignable to unknown , never is assignable to everything. Nothing is assignable to never , unknown is not assignable to anything (except any ).
  • void is not assignable to or from anything, with the following exceptions: any , unknown , never , undefined , and null (if strictNullChecks is off, see table for details).
  • When strictNullChecks is off, null and undefined are similar to never : assignable to most types, most types are not assignable to them. They are assignable to each other.
  • When strictNullChecks is on, null and undefined behave more like void : not assignable to or from anything, except for any , unknown , and void ( undefined is always assignable to void ).

Nightly Builds

How to use a nightly build of TypeScript

The TypeScript docs are an open source project. Help us improve these pages by sending a Pull Request ❤

Ryan Cavanaugh  (51)

Last updated: Aug 26, 2024  

  • Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers
  • Advertising & Talent Reach devs & technologists worldwide about your product, service or employer brand
  • OverflowAI GenAI features for Teams
  • OverflowAPI Train & fine-tune LLMs
  • Labs The future of collective knowledge sharing
  • About the company Visit the blog

Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Get early access and see previews of new features.

destructuring with spread operator and typing

I have this object:

I can destructure it, collect the rest of it using the "spread" operator, and type the variables like this:

But how do I also type the restOfIt on the same line? The following all fail:

TypeScript playground here

  • destructuring
  • object-destructuring

Marcus Junius Brutus's user avatar

  • Why do you need to explicitly annotate it? TypeScript should be able to infer the types for you. –  mochaccino Commented Sep 6, 2022 at 13:54

You can use dynamic key definition

If you know all types in restOfIt is number , you also can use number instead of any which is better

If you already have a type for restOfIt , you can use type union

Nick Vu's user avatar

  • This would break if a or b is not number –  Tobias S. Commented Sep 6, 2022 at 11:55
  • This works but apparently, in the general case, it can't be made as strict / rigorous as one would want it too. E.g. suppose I had already defined a type CD for the restOfIt . How would I assert that the restOfIt is of type CD ? –  Marcus Junius Brutus Commented Sep 6, 2022 at 11:57
  • @TobiasS. hmm from the question, he defined a and b as a number type –  Nick Vu Commented Sep 6, 2022 at 12:00
  • 1 @MarcusJuniusBrutus I added the part related to CD type as you mentioned, we can use type union in that case –  Nick Vu Commented Sep 6, 2022 at 12:00
  • @NickVu quite close now but still, the above code does not really assert the type of restOfIt under certain cases. E.g. if I had type CD = {a: number, c: number, d: number} , that would still type check because the entirety of the values is compared against the entirety of the type. –  Marcus Junius Brutus Commented Sep 6, 2022 at 12:19

Your Answer

Reminder: Answers generated by artificial intelligence tools are not allowed on Stack Overflow. Learn more

Sign up or log in

Post as a guest.

Required, but never shown

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy .

Not the answer you're looking for? Browse other questions tagged typescript destructuring object-destructuring or ask your own question .

  • The Overflow Blog
  • Where does Postgres fit in a world of GenAI and vector databases?
  • Featured on Meta
  • We've made changes to our Terms of Service & Privacy Policy - July 2024
  • Bringing clarity to status tag usage on meta sites
  • What does a new user need in a homepage experience on Stack Overflow?
  • Feedback requested: How do you use tag hover descriptions for curating and do...
  • Staging Ground Reviewer Motivation

Hot Network Questions

  • How is yield calculated for a portfolio?
  • Is it possible to configure an eqnarry environment to automatically split over multiple pags
  • My school wants me to download an SSL certificate to connect to WiFi. Can I just avoid doing anything private while on the WiFi?
  • Are there any theoretical reasons why we cannot measure the position of a particle with zero error?
  • How bad would near constant dreary/gloomy/stormy weather on our or an Earthlike world be for us and the environment?
  • Can I use "historically" to mean "for a long time" in "Historically, the Japanese were almost vegetarian"?
  • How would increasing atomic bond strength affect nuclear physics?
  • Meaning of “ ’thwart” in a 19th century poem
  • pgf plots-Shifting the tick label down while changing the decimal seperator to comma (,)
  • Why does Russia strike electric power in Ukraine?
  • about flag changes in 16-bit calculations on the MC6800
  • Using "no" at the end of a statement instead of "isn't it"?
  • Is it advisable to contact faculty members at U.S. universities prior to submitting a PhD application?
  • How are notes named in Japan?
  • CPU is idle, but huge load, and NFS client stop responding
  • How to attach a 4x8 plywood to a air hockey table
  • Completely introduce your friends
  • `Drop` for list of elements of different dimensions
  • My visit is for two weeks but my host bought insurance for two months is it okay
  • Why is one of the Intel 8042 keyboard controller outputs inverted?
  • Could someone tell me what this part of an A320 is called in English?
  • How do you determine what order to process chained events/interactions?
  • Reusing own code at work without losing licence
  • Small proofs for large sums

typescript spread assignment

COMMENTS

  1. TypeScript: Documentation

    var declarations. Declaring a variable in JavaScript has always traditionally been done with the var keyword. var a = 10; As you might've figured out, we just declared a variable named a with the value 10. We can also declare a variable inside of a function: function f() {.

  2. javascript

    For reference object rest/spread is finalised in ECMAScript 2018 as a stage 4. The proposal can be found here. For the most part object assign and spread work the same way, the key difference is that spread defines properties, whilst Object.assign () sets them. This means Object.assign () triggers setters.

  3. Mastering the Spread Operator in Node.js and TypeScript

    This comprehensive guide delves into the spread operator, a powerful tool in JavaScript and TypeScript. It starts with an introduction to the spread operator, explaining its purpose and significance in modern programming. The guide then explores its usage in Node.js, showcasing practical examples of copying arrays, merging objects, and spreading function arguments. Moving on to TypeScript, it ...

  4. Mastering TypeScript's Spread Operator for Cleaner, More ...

    Mastering TypeScript's Spread Operator for Cleaner, More Flexible Code. The spread operator in TypeScript is a powerful feature that allows you to easily expand the contents of an array or object. This can come in handy when you need to make a copy of an existing object or array, or when you want to merge multiple array s or objects together.

  5. TypeScript / JavaScript Spread Operator (with Examples)

    2. Spread Operator Example. Let us check out a few examples of the spread operator to understand its usage better. 2.1. Initialize a New Array from Another Array. We can use the spread operator to create arrays from existing arrays in the given fashion. let origArrayOne = [ 1, 2, 3]; //1,2,3 let origArrayTwo = [ 4, 5, 6]; //4,5,6 //Create new ...

  6. How To Use The Spread Operator In TypeScript?

    Using the spread operator with an array. A developer can use the spread operator to copy an array in TypeScript. Here is an example: typescript const numbers = [ 25, 49, 29 ]; const copy = [...numbers]; // Outputs: [25, 49, 29] console .log(copy); As you can see, copy now contains all the elements from the array called numbers.

  7. Object Rest and Spread in TypeScript

    Object Rest and Spread in TypeScript December 23, 2016. TypeScript 2.1 adds support for the Object Rest and Spread Properties proposal that is slated for standardization in ES2018. You can work with rest and spread properties in a type-safe manner and have the compiler downlevel both features all the way down to ES3.

  8. Spread Operator

    Array Assignment. The spread operator allows you to easily place an expanded version of an array into another array. This is demonstrated in the example below: var list = [1, 2]; list = [...list, 3, 4]; console.log(list); // [1,2,3,4] You can put the expanded array in at any position, and get the effect you'd expect: var list = [1, 2]; list ...

  9. The Spread Operator and Objects

    Simple copy. You can spread an object similar to an array. Spreading an object is handy in a scenario where you need to create a clone for immutability purposes or if you are already using the function Object.assign.. The assign method is similar in functionality but uses a more verbose syntax. The syntax for the spread operator is identical to the spread for an array which means that it uses ...

  10. Master Spread Operator With TypeScript

    Also worth noting that when we have a property with an object as a value, the spread operator copies its values. So, changes in the original object will not impact the newly created one. Photo Credit: Karolína Maršálková. The rest operator. The spread operator has a very friendly sibling; the rest operator. Both of them share the three ...

  11. How to use Spread Operator in TypeScript

    The spread operator in TypeScript simplifies array and object manipulation by enabling easy copying, combining, and property modification. Its concise syntax enhances code readability and efficiency, making it an essential tool for modern TypeScript development. FAQs-Spread Operator in TypeScript

  12. Spread syntax (...)

    The spread (...) syntax allows an iterable, such as an array or string, to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected. In an object literal, the spread syntax enumerates the properties of an object and adds the key-value pairs to the object being created. Spread syntax looks exactly like rest syntax.

  13. 6 Awesome Tricks with the Spread and Rest Operators in Typescript and

    console.log(newCat); the rest operator here means "combine the rest of the properties in a new object". and it will give us this result: output. and just like extracting properties, modifying cat properties will not update the values for newCat, as it is a completely new object: const cat = {. name: "chase",

  14. Operators in TypeScript

    Assignment operators. Assignment operators in TypeScript are used to assign values to variables. The most basic operator is the simple assignment operator (=), which assigns the right-hand operand to the left-hand operand. Other compound operators, like +=, -=, *=, and /=, perform an operation and assignment in one step.

  15. Destructuring

    The method of structuring in JavaScript is the object literal: var foo = { bar: { bas: 123 } }; Without the awesome structuring support built into JavaScript, creating new objects on the fly would indeed be very cumbersome. Destructuring brings the same level of convenience to getting data out of a structure.

  16. javascript

    When trying to spread into array, one gets Uncaught TypeError: boolean false is not iterable (cannot read property Symbol(Symbol.iterator)). - Qwerty. Commented May 20, 2020 at 14:04. 2. I didn't know this can be done. Really concise in certain use cases. Nice! - Daniel San.

  17. Copying Classes in TypeScript -- Visual Studio Magazine

    Copying Classes in TypeScript. If you need to create a version of a class from several sources or just want to merge default values with a user's input, object spreading solves your problem. JavaScript won't let you do this (yet) but TypeScript will. By Peter Vogel; 03/06/2018

  18. Understanding Destructuring, Rest Parameters, and Spread Syntax in

    Spread syntax is used to unpack iterables such as arrays, objects, and function calls. Rest parameter syntax will create an array from an indefinite number of values. Destructuring, rest parameters, and spread syntax are useful features in JavaScript that help keep your code succinct and clean.

  19. typescript

    TS infers T based on all the input elements, widening them as appropriate - so spread([1,2,3]) would return a number[], but spread([1,2,"abc"]) would return (string|number)[]. If you wanted to keep T as the type of the input array itself, you could achieve that same result kinda cutely using TS's tuple spreading to define the return type:

  20. TypeScript: Documentation

    So far, we've used "compatible", which is not a term defined in the language spec. In TypeScript, there are two kinds of compatibility: subtype and assignment. These differ only in that assignment extends subtype compatibility with rules to allow assignment to and from any, and to and from enum with corresponding numeric values.

  21. What Kamala Harris Was Really Saying in Her Convention Speech

    Kamala Harris proved in her acceptance speech Thursday night that she understood the assignment. She's already a unique presidential nominee, a biracial woman with a blended family.

  22. Trying to use the spread operator with TypeScript and Object.assign

    That will now allow you to spread into Object.assign(): and the type of result is known to be an intersection type similar to {foo: {name: string}, bar: {name: string}, baz: {name: string}}. This is my suggested solution, I think. You could try to tell the compiler that sampleStrings is an n-tuple (using, for example, a const assertion ), and ...

  23. typescript

    Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers; Advertising & Talent Reach devs & technologists worldwide about your product, service or employer brand; OverflowAI GenAI features for Teams; OverflowAPI Train & fine-tune LLMs; Labs The future of collective knowledge sharing; About the company Visit the blog