Object destructuring with types in TypeScript

Object destructuring is a powerful feature of JavaScript and TypeScript that can help you write cleaner and more expressive code. This syntax allows you to extract properties from an object and assign them to variables or parameters.

You can use object destructuring to create variables, assign default values, rename properties, or omit some properties.

In TypeScript, you can also specify the type of the object or the properties that you are destructuring. There are two ways to do this:

  • You can use a type annotation after the destructuring pattern, like this:

This tells TypeScript that the object you are destructuring has two properties, name and age, and they are both of type string and number respectively.

  • You can use an interface or a type alias to define the shape of the object, and then use it as a type annotation, like this:

This tells TypeScript that the object you are destructuring conforms to the Person interface, which has two properties, name and age, of type string and number respectively.

Using an interface or a type alias can be more convenient and reusable than writing the type annotation inline, especially if you have complex or nested objects.

You can also use object destructuring in function parameters, which can make your code more concise and readable. For example, instead of writing a function like this:

You can write it like this:

This way, you don’t have to repeat the person parameter inside the function body, and you can directly access the name and age properties.

Object destructuring with types in TypeScript

I was using TypeScript in Deno to build a sample project and I had to destructure an object. I am familiar with TypeScript basics but sometimes I hit a problem.

Object destructuring was one of those.

I wanted to do

I tried adding the string and number types like this:

But this didn’t work. It apparently worked, but in reality this is assigning the name property to the string variable, and the age property value to the number variable.

The correct syntax is this:

The best way to approach this would be to create a type or interface for that data:

Then you can write the above in this way, which is shorter:

Here is how can I help you:

  • COURSES where I teach everything I know
  • THE VALLEY OF CODE your web development manual
  • BOOTCAMP 2024 cohort in progress, next edition in 2025
  • BOOKS 16 coding ebooks you can download for free on JS Python C PHP and lots more
  • SOLO LAB everything I know about running a lifestyle business as a solopreneur
  • Interesting links collection
  • Follow me on X

Was this page helpful?

Variable Declaration

let and const are two relatively new concepts for variable declarations in JavaScript. As we mentioned earlier , let is similar to var in some respects, but allows users to avoid some of the common “gotchas” that users run into in JavaScript.

const is an augmentation of let in that it prevents re-assignment to a variable.

With TypeScript being an extension of JavaScript, the language naturally supports let and const . Here we’ll elaborate more on these new declarations and why they’re preferable to var .

If you’ve used JavaScript offhandedly, the next section might be a good way to refresh your memory. If you’re intimately familiar with all the quirks of var declarations in JavaScript, you might find it easier to skip ahead.

var declarations

Declaring a variable in JavaScript has always traditionally been done with the var keyword.

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:

and we can also access those same variables within other functions:

In this above example, g captured the variable a declared in f . At any point that g gets called, the value of a will be tied to the value of a in f . Even if g is called once f is done running, it will be able to access and modify a .

Scoping rules

var declarations have some odd scoping rules for those used to other languages. Take the following example:

Some readers might do a double-take at this example. The variable x was declared within the if block , and yet we were able to access it from outside that block. That’s because var declarations are accessible anywhere within their containing function, module, namespace, or global scope - all which we’ll go over later on - regardless of the containing block. Some people call this var -scoping or function-scoping . Parameters are also function scoped.

These scoping rules can cause several types of mistakes. One problem they exacerbate is the fact that it is not an error to declare the same variable multiple times:

Maybe it was easy to spot out for some experienced JavaScript developers, but the inner for -loop will accidentally overwrite the variable i because i refers to the same function-scoped variable. As experienced developers know by now, similar sorts of bugs slip through code reviews and can be an endless source of frustration.

Variable capturing quirks

Take a quick second to guess what the output of the following snippet is:

For those unfamiliar, setTimeout will try to execute a function after a certain number of milliseconds (though waiting for anything else to stop running).

Ready? Take a look:

Many JavaScript developers are intimately familiar with this behavior, but if you’re surprised, you’re certainly not alone. Most people expect the output to be

Remember what we mentioned earlier about variable capturing? Every function expression we pass to setTimeout actually refers to the same i from the same scope.

Let’s take a minute to consider what that means. setTimeout will run a function after some number of milliseconds, but only after the for loop has stopped executing; By the time the for loop has stopped executing, the value of i is 10 . So each time the given function gets called, it will print out 10 !

A common work around is to use an IIFE - an Immediately Invoked Function Expression - to capture i at each iteration:

This odd-looking pattern is actually pretty common. The i in the parameter list actually shadows the i declared in the for loop, but since we named them the same, we didn’t have to modify the loop body too much.

let declarations

By now you’ve figured out that var has some problems, which is precisely why let statements were introduced. Apart from the keyword used, let statements are written the same way var statements are.

The key difference is not in the syntax, but in the semantics, which we’ll now dive into.

Block-scoping

When a variable is declared using let , it uses what some call lexical-scoping or block-scoping . Unlike variables declared with var whose scopes leak out to their containing function, block-scoped variables are not visible outside of their nearest containing block or for -loop.

Here, we have two local variables a and b . a ’s scope is limited to the body of f while b ’s scope is limited to the containing if statement’s block.

Variables declared in a catch clause also have similar scoping rules.

Another property of block-scoped variables is that they can’t be read or written to before they’re actually declared. While these variables are “present” throughout their scope, all points up until their declaration are part of their temporal dead zone . This is just a sophisticated way of saying you can’t access them before the let statement, and luckily TypeScript will let you know that.

Something to note is that you can still capture a block-scoped variable before it’s declared. The only catch is that it’s illegal to call that function before the declaration. If targeting ES2015, a modern runtime will throw an error; however, right now TypeScript is permissive and won’t report this as an error.

For more information on temporal dead zones, see relevant content on the Mozilla Developer Network .

Re-declarations and Shadowing

With var declarations, we mentioned that it didn’t matter how many times you declared your variables; you just got one.

In the above example, all declarations of x actually refer to the same x , and this is perfectly valid. This often ends up being a source of bugs. Thankfully, let declarations are not as forgiving.

The variables don’t necessarily need to both be block-scoped for TypeScript to tell us that there’s a problem.

That’s not to say that a block-scoped variable can never be declared with a function-scoped variable. The block-scoped variable just needs to be declared within a distinctly different block.

The act of introducing a new name in a more nested scope is called shadowing . It is a bit of a double-edged sword in that it can introduce certain bugs on its own in the event of accidental shadowing, while also preventing certain bugs. For instance, imagine we had written our earlier sumMatrix function using let variables.

This version of the loop will actually perform the summation correctly because the inner loop’s i shadows i from the outer loop.

Shadowing should usually be avoided in the interest of writing clearer code. While there are some scenarios where it may be fitting to take advantage of it, you should use your best judgement.

Block-scoped variable capturing

When we first touched on the idea of variable capturing with var declaration, we briefly went into how variables act once captured. To give a better intuition of this, each time a scope is run, it creates an “environment” of variables. That environment and its captured variables can exist even after everything within its scope has finished executing.

Because we’ve captured city from within its environment, we’re still able to access it despite the fact that the if block finished executing.

Recall that with our earlier setTimeout example, we ended up needing to use an IIFE to capture the state of a variable for every iteration of the for loop. In effect, what we were doing was creating a new variable environment for our captured variables. That was a bit of a pain, but luckily, you’ll never have to do that again in TypeScript.

let declarations have drastically different behavior when declared as part of a loop. Rather than just introducing a new environment to the loop itself, these declarations sort of create a new scope per iteration . Since this is what we were doing anyway with our IIFE, we can change our old setTimeout example to just use a let declaration.

and as expected, this will print out

const declarations

const declarations are another way of declaring variables.

They are like let declarations but, as their name implies, their value cannot be changed once they are bound. In other words, they have the same scoping rules as let , but you can’t re-assign to them.

This should not be confused with the idea that the values they refer to are immutable .

Unless you take specific measures to avoid it, the internal state of a const variable is still modifiable. Fortunately, TypeScript allows you to specify that members of an object are readonly . The chapter on Interfaces has the details.

let vs. const

Given that we have two types of declarations with similar scoping semantics, it’s natural to find ourselves asking which one to use. Like most broad questions, the answer is: it depends.

Applying the principle of least privilege , all declarations other than those you plan to modify should use const . The rationale is that if a variable didn’t need to get written to, others working on the same codebase shouldn’t automatically be able to write to the object, and will need to consider whether they really need to reassign to the variable. Using const also makes code more predictable when reasoning about flow of data.

Use your best judgement, and if applicable, consult the matter with the rest of your team.

The majority of this handbook uses let declarations.

Destructuring

Another ECMAScript 2015 feature that TypeScript has is destructuring. For a complete reference, see the article on the Mozilla Developer Network . In this section, we’ll give a short overview.

Array destructuring

The simplest form of destructuring is array destructuring assignment:

This creates two new variables named first and second . This is equivalent to using indexing, but is much more convenient:

Destructuring works with already-declared variables as well:

And with parameters to a function:

You can create a variable for the remaining items in a list using the syntax ... :

Of course, since this is JavaScript, you can just ignore trailing elements you don’t care about:

Or other elements:

Tuple destructuring

Tuples may be destructured like arrays; the destructuring variables get the types of the corresponding tuple elements:

It’s an error to destructure a tuple beyond the range of its elements:

As with arrays, you can destructure the rest of the tuple with ... , to get a shorter tuple:

Or ignore trailing elements, or other elements:

Object destructuring

You can also destructure objects:

This creates new variables a and b from o.a and o.b . Notice that you can skip c if you don’t need it.

Like array destructuring, you can have assignment without declaration:

Notice that we had to surround this statement with parentheses. JavaScript normally parses a { as the start of block.

You can create a variable for the remaining items in an object using the syntax ... :

Property renaming

You can also give different names to properties:

Here the syntax starts to get confusing. You can read a: newName1 as ” a as newName1 ”. The direction is left-to-right, as if you had written:

Confusingly, the colon here does not indicate the type. The type, if you specify it, still needs to be written after the entire destructuring:

Default values

Default values let you specify a default value in case a property is undefined:

In this example the b? indicates that b is optional, so it may be undefined . keepWholeObject now has a variable for wholeObject as well as the properties a and b , even if b is undefined.

Function declarations

Destructuring also works in function declarations. For simple cases this is straightforward:

But specifying defaults is more common for parameters, and getting defaults right with destructuring can be tricky. First of all, you need to remember to put the pattern before the default value.

The snippet above is an example of type inference, explained earlier in the handbook.

Then, you need to remember to give a default for optional properties on the destructured property instead of the main initializer. Remember that C was defined with b optional:

Use destructuring with care. As the previous example demonstrates, anything but the simplest destructuring expression is confusing. This is especially true with deeply nested destructuring, which gets really hard to understand even without piling on renaming, default values, and type annotations. Try to keep destructuring expressions small and simple. You can always write the assignments that destructuring would generate yourself.

The spread operator is the opposite of destructuring. It allows you to spread an array into another array, or an object into another object. For example:

This gives bothPlus the value [0, 1, 2, 3, 4, 5] . Spreading creates a shallow copy of first and second . They are not changed by the spread.

You can also spread objects:

Now search is { food: "rich", price: "$$", ambiance: "noisy" } . Object spreading is more complex than array spreading. Like array spreading, it proceeds from left-to-right, but the result is still an object. This means that properties that come later in the spread object overwrite properties that come earlier. So if we modify the previous example to spread at the end:

Then the food property in defaults overwrites food: "rich" , which is not what we want in this case.

Object spread also has a couple of other surprising limits. First, it only includes an objects’ own, enumerable properties . Basically, that means you lose methods when you spread instances of an object:

Second, the TypeScript compiler doesn’t allow spreads of type parameters from generic functions. That feature is expected in future versions of the language.

using declarations

using declarations are an upcoming feature for JavaScript that are part of the Stage 3 Explicit Resource Management proposal. A using declaration is much like a const declaration, except that it couples the lifetime of the value bound to the declaration with the scope of the variable.

When control exits the block containing a using declaration, the [Symbol.dispose]() method of the declared value is executed, which allows that value to perform cleanup:

At runtime, this has an effect roughly equivalent to the following:

using declarations are extremely useful for avoiding memory leaks when working with JavaScript objects that hold on to native references like file handles

or scoped operations like tracing

Unlike var , let , and const , using declarations do not support destructuring.

null and undefined

It’s important to note that the value can be null or undefined , in which case nothing is disposed at the end of the block:

which is roughly equivalent to:

This allows you to conditionally acquire resources when declaring a using declaration without the need for complex branching or repetition.

Defining a disposable resource

You can indicate the classes or objects you produce are disposable by implementing the Disposable interface:

await using declarations

Some resources or operations may have cleanup that needs to be performed asynchronously. To accommodate this, the Explicit Resource Management proposal also introduces the await using declaration:

An await using declaration invokes, and awaits , its value’s [Symbol.asyncDispose]() method as control leaves the containing block. This allows for asynchronous cleanup, such as a database transaction performing a rollback or commit, or a file stream flushing any pending writes to storage before it is closed.

As with await , await using can only be used in an async function or method, or at the top level of a module.

Defining an asynchronously disposable resource

Just as using relies on objects that are Disposable , an await using relies on objects that are AsyncDisposable :

await using vs await

The await keyword that is part of the await using declaration only indicates that the disposal of the resource is await -ed. It does not await the value itself:

await using and return

It’s important to note that there is a small caveat with this behavior if you are using an await using declaration in an async function that returns a Promise without first await -ing it:

Because the returned promise isn’t await -ed, it’s possible that the JavaScript runtime may report an unhandled rejection since execution pauses while await -ing the asynchronous disposal of x , without having subscribed to the returned promise. This is not a problem that is unique to await using , however, as this can also occur in an async function that uses try..finally :

To avoid this situation, it is recommended that you await your return value if it may be a Promise :

using and await using in for and for..of statements

Both using and await using can be used in a for statement:

In this case, the lifetime of x is scoped to the entire for statement and is only disposed when control leaves the loop due to break , return , throw , or when the loop condition is false.

In addition to for statements, both declarations can also be used in for..of statements:

Here, x is disposed at the end of each iteration of the loop , and is then reinitialized with the next value. This is especially useful when consuming resources produced one at a time by a generator.

using and await using in older runtimes

using and await using declarations can be used when targeting older ECMAScript editions as long as you are using a compatible polyfill for Symbol.dispose / Symbol.asyncDispose , such as the one provided by default in recent editions of NodeJS.

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

Daniel Rosenwasser  (58)

Last updated: Apr 12, 2024  

Destructuring Object parameters in TypeScript functions

avatar

Last updated: Feb 27, 2024 Reading time · 3 min

banner

# Destructuring Object parameters in TypeScript functions

When destructuring object parameters in a function, separate the destructured parameters and the type for the specific properties with a colon

destructuring object parameters in typescript function

Unfortunately, when destructuring parameters in TypeScript functions, we have to repeat the properties when typing them.

The first example shows how to destructure the name and age properties of an object parameter.

We didn't provide default values for the properties in the first example and both of the properties are required because they weren't marked as optional using a question mark.

# Destructuring Object parameters with default values

The second example shows how to destructure two properties from an object and set a default value for one of the properties.

destructuring object parameters with default value

We set a default value for the name property when destructuring it. Note that we used a question mark to mark the property as optional.

If you have default values for all of the object's properties, set a default value for the entire object instead.

This is better than setting a default value for each property when destructuring because you'd still have to pass an empty object to the function.

Even though we provided default values for all of the object's properties when destructuring, we are still required to pass an empty object because the object itself is required.

# Using a Type Alias or an Interface

If your function declaration gets too busy, use a type alias .

using type alias or interface

This is a bit easier to read, as we can clearly see that the name property has a default value and the function expects an object of type GetPersonParams .

# Using destructuring inside of a function's body

Alternatively, you can use destructuring inside of the function's body.

Which approach you pick is a matter of personal preference. You can set default values when destructuring inside of the function's body as well.

If you need to pass a function as a parameter, check out the following article .

book cover

Borislav Hadzhiev

Web Developer

buy me a coffee

Copyright © 2024 Borislav Hadzhiev

How to do object destructuring with types in TypeScript?

April 12, 2021 - 2 min read

Sometimes when you destructure object properties in TypeScript, you may want to define the type for the property you are destructuring.

For example, let's say I have an object called John with some properties like age , isAdult like this,

Now let's use the destructuring operator ( {} curly braces) to get the age property from the John object like this,

To set or define a type on the age property we can use a colon : after the destructuring operator and then open a curly brace and then define the type of the age property inside that curly brace like this,

See the above code live in codesandbox

There is one more way of defining the type using an interface like this,

That's it! 😃

Feel free to share if you found this useful 😃.

Marius Schulz

Typing Destructured Object Parameters in TypeScript

In TypeScript, you can add a type annotation to each formal parameter of a function using a colon and the desired type, like this:

That way, your code doesn't compile when you attempt to call the function with an argument of an incompatible type, such as number or boolean . Easy enough.

Let's now look at a function declaration that makes use of destructuring assignment with an object parameter, a feature that was introduced as part of ECMAScript 2015. The toJSON function accepts a value of any type that should be stringified as JSON. It additionally accepts a settings parameter that allows the caller to provide configuration options via properties:

The type of the value parameter is explicitly given as any , but what type does the pretty property have? We haven't explicitly specified a type, so it's implicitly typed as any . Of course, we want it to be a boolean, so let's add a type annotation:

However, that doesn't work. The TypeScript compiler complains that it can't find the name pretty that is used within the function body. This is because boolean is not a type annotation in this case, but the name of the local variable that the value of the pretty property gets assigned to. Again, this is part of the specification of how object destructuring works.

Because TypeScript is a superset of JavaScript, every valid JavaScript file is a valid TypeScript file (set aside type errors, that is). Therefore, TypeScript can't simply change the meaning of the destructuring expression { pretty: boolean } . It looks like a type annotation, but it's not.

# Typing Immediately Destructured Parameters

Of course, TypeScript offers a way to provide an explicit type annotation. It's a little verbose, yet (if you think about it) consistent:

You're not directly typing the pretty property, but the settings object it belongs to, which is the actual parameter passed to the toJSON function. If you now try to compile the above TypeScript code, the compiler doesn't complain anymore and emits the following JavaScript function:

# Providing Default Values

To call the above toJSON function, both the value and the settings parameter have to be passed. However, it might be reasonable to use default settings if they aren't explicitly specified. Assuming that pretty should be true by default, we'd like to be able to call the function in the following various ways:

The function call #1 already works because all parameters are specified. In order to enable function call #2, we have to mark the pretty property as optional by appending a question mark to the property name within the type annotation. Additionally, the pretty property gets a default value of true if it's not specified by the caller:

Finally, function call #3 is made possible by providing a default value of {} for the destructuring pattern of the settings object. If no settings object is passed at all, the empty object literal {} is being destructured. Because it doesn't specify a value for the pretty property, its fallback value true is returned:

Here's what the TypeScript compiler emits when targeting "ES5" :

When targeting "ES6" , only the type information is removed:

# Extracting a Type for the Settings Parameter

With multiple properties, the inline type annotation gets unwieldy quickly, which is why it might a good idea to create an interface for the configuration object:

You can now type the settings parameter using the new interface type:

TypeScript Topics

Typescript destructuring.

Switch to English

Table of Contents

Introduction

Destructuring arrays, destructuring objects, advanced destructuring, tips and tricks.

  • Basic Array Destructuring
  • Ignoring Values
  • Basic Object Destructuring
  • Renaming Variables
  • Default Values
  • Nested Destructuring
  • Error-Prone Cases
  • Using Destructuring in Function Parameters

Popular Articles

  • Typescript Unknown Vs Any (Dec 06, 2023)
  • Typescript Undefined (Dec 06, 2023)
  • Typescript Type Definition (Dec 06, 2023)
  • Typescript Splice (Dec 06, 2023)
  • Typescript Return Type Of Function (Dec 06, 2023)
  • Web Development

How to Specify Types for Destructured Object Properties Using TypeScript?

  • Daniyal Hamid
  • 09 Aug, 2020

You can simply specify the type of an object you're destructuring after : . The type can either be specified inline, or from an existing interface, type declaration, or by using type assertions.

Infer Types From Object's Type Declaration

Ideally, you should correctly type the object wherever possible because if the object itself has a type declaration, then TypeScript would infer those types automatically when you're destructuring an object. This is perhaps the best way to go about it.

Also, remember that TypeScript can automatically determine the types of object properties based on their values even without any explicit type declarations. However, for complex types, and even generally speaking, it's always a good idea to properly type objects to avoid unintended results. After all, that is the whole purpose of using TypeScript in a project.

Inline Typing an Object:

Adding object type using an interface:, adding object type using a type declaration:, asserting object type:.

Sometimes the type of an object could be more specific than its current type (like when an object has an any or unknown type):

In such cases we could assert the object type in any of the following ways:

You can also use the angeled-brackets syntax (i.e. <FooBar>obj ) for type assertions, which is equivalent to the "as" syntax (e.g. obj as FooBar ). Although using either one is a matter of preference, one key difference is that the angeled-bracket syntax is not supported when using TypeScript with JSX.

Explicitly Typing Object Properties:

In some cases, you might find the need to declare types for object properties explicitly while destructuring (such as when the object is not correctly type — i.e. when it has any or unknown types). In such cases, you could do any of the following:

Inline Typing Destructured Properties

Adding types for destructured properties using an interface:, adding types for destructured properties using a type declaration:.

This post was published 09 Aug, 2020 by Daniyal Hamid . Daniyal currently works as the Head of Engineering in Germany and has 20+ years of experience in software engineering, design and marketing. Please show your love and support by sharing this post .

const t="undefined"!=typeof HTMLImageElement&&"loading"in HTMLImageElement.prototype;if(t){const t=document.querySelectorAll("img[data-main-image]");for(let e of t){e.dataset.src&&(e.setAttribute("src",e.dataset.src),e.removeAttribute("data-src")),e.dataset.srcset&&(e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset"));const t=e.parentNode.querySelectorAll("source[data-srcset]");for(let e of t)e.setAttribute("srcset",e.dataset.srcset),e.removeAttribute("data-srcset");e.complete&&(e.style.opacity=1,e.parentNode.parentNode.querySelector("[data-placeholder-image]").style.opacity=0)}} barbarian meets coding

Webdev, ux & a pinch of fantasy, argument destructuring and type annotations in typescript.

I often use destructuring in ES6 when I want to have a function with an options object. I described options objects in ” More useful function patterns - function overloading as a way to achieve function overloading in JavaScript with the added benefits of named arguments and extensibility.

Recently I was trying to use the same pattern in TypeScript adding some type annotations but it did not work! If you have had the same issue yourself read through to find out how to solve it.

A Screenshot of me testing destructuring in TypeScript

Options Objects

Here’s an example of an options object from the aforementioned article to give you an idea of what I am talking about:

This is ES5 but it can be rewritten using ES6 destructuring and defaults ( you can check this article if you want to learn more about ES6 Destructuring by the by ):

Arguments Destructuring in TypeScript

So I was trying to follow this pattern in TypeScript and I started by writing the following ES6 code:

Which you can evaluate providing different arguments:

The next step was to add type annotations to this previous example. So I went and added them:

But when I tried to call that function everything exploded!

What? What? What? I asked myself… isn’t TypeScript supposed to be a superset of ES6?

Then I realized that type annotations syntax conflicts with ES6 destructuring syntax. For instance, you can use the : with destructuring to extract and project a value to a different variable than in the original object:

So it makes sense that TypeScript doesn’t attempt to redefine the meaning of : in this particular case where it has an specific meaning in ES6. Otherwise it wouldn’t be a superset of ES6 but a different language.

So, is there a way we can still get type annotations in this scenario? Yes it is. And you can thank Anders Hejlsberg for his super quick answer . You can add top level type annotations like this:

Which works just as you would expect and gives you type annotations with type safety and nice intellisense:

It is a little bit wordy though so you may consider splitting it like this:

And that’s it! Now you can use destructuring, defaults and type annotations.

Have a nice Friday and an even better weekend! :)

Jaime González García

Written by Jaime González García , dad, husband, software engineer, ux designer, amateur pixel artist, tinkerer and master of the arcane arts. You can also find him on Twitter jabbering about random stuff. Jaime González García

Carl Rippon

Building SPAs

Strongly-typed destructuring and rest parameters.

Destructuring assignment and rest parameters are awesome and typical in codebases these days. Is it possible to strongly-type these though in TypeScript? Let’s find out.

TypeScript has tuples

Before we figure out how to strongly-type rest parameters, let’s understand tuples. A tuple can be thought of as an array with a fixed number of elements. They are nice for small and obvious data structures. For example, the useState React hook returns a tuple:

TypeScript lets us define tuples in a type annotation by specifying the type of each element in square brackets. For example:

Open-ended tuples

What have tuples got to do with rest parameters? Well, we’ll get there eventually.

TypeScript lets us have tuples where we can have a varying number of end elements like below:

We can specify the type for the above example as [string, ...number[]] .

Strongly-typing rest parameters

I wonder if we can use an open-ended tuple to strongly-type a rest parameter? Let’s try to do this for the scores parameter in the function below:

Let’s try this:

If we think about it, [...number[]] is just number[] . So, this can be simplified to:

… and if we consume the function:

Great - it works!

Strongly-typing destructured assignment

Specifying the type on destructured object variables is perhaps not achieved how you might first expect. The following doesn’t specify type annotations for firstName and score :

Instead, it specifies names for the destructured variables:

We specify the type annotation after the destructured object as follows:

If we are destructuring a tuple, we specify the tuple type after the destructured tuple:

We can specify a type on an open-ended tuple as follows:

It is worth noting that often TypeScript cleverly infers the types of destructured elements, but it is good to know how to specify type annotation in the edge cases where it doesn’t.

TypeScript tuples are a convenient way of strongly-typing small and obvious data structures. Open-ended tuples can be used to strongly-type rest parameters. TypeScript generally smartly infers the types of destructured elements for us, but when it can’t, we can simply put a type annotation after the destructured items.

If you to learn more about TypeScript, you may find my free TypeScript course useful:

Learn TypeScript

Learn TypeScript

Course Thumbnail of Beginners Guide to TypeScript

  • Beginners Guide to TypeScript

Getting Started With TypeScript

  • Introduction
  • What is TypeScript?
  • JavaScript vs. TypeScript Example
  • Untyped JavaScript
  • Catching Errors with Types
  • Why Should I Use TypeScript?

Setting Up Your TypeScript Development Environment

  • Setting up your development environment
  • Code editor
  • Node.js and npm
  • Getting Started
  • Initialize package.json
  • Install TypeScript
  • Install ts-node
  • Initialize tsconfig.json

Planning Our First TypeScript Application: FinanceMe

  • Building FinanceMe
  • Planning FinanceMe
  • Example Usage
  • Class Diagram of FinanceMe

Classes in TypeScript: User and Expense

  • TypeScript Classes
  • Expense Class

Generating Unique Ids

  • Generating Unique Ids For Each Expense
  • Add genUniqueId to Expense
  • Putting It Together

Generating the Budget Class

  • Budget Class
  • Five New Methods
  • Category enum
  • Grouping Expenses in a Budget

Tracking Expenses by Month and Users

  • TrackedMonth Class

TypeScript Language Features

  • Primitive Types
  • Number Literal Types
  • Numeric Separators
  • String Literal Types
  • null and undefined

Lists with Arrays and Tuples

  • Optional Elements

Chapter 10:

Enums are for named constants.

  • Enums have a value
  • Reverse Mappings

Chapter 11:

Typing objects.

  • Object Types
  • The object type
  • Typing object properties
  • Optional properties

Chapter 12:

Union types, discriminated unions, and type guards.

  • Union Types Denote "or"
  • Discriminated Unions
  • Type Guards

Chapter 13:

Intersection types.

  • Intersection Types Express "and"
  • Optional Properties are Optional
  • Shared Properties are Intersections

Chapter 14:

Typing functions - the basics.

  • Annotating Functions
  • Optional Parameters
  • Default Parameters
  • Rest Parameters

Chapter 15:

Typing functions with overloading, values, and arrow functions.

  • Overloading
  • Functions as values
  • Arrow functions

Chapter 16:

Imports and exports with typescript modules.

  • TypeScript Modules
  • Named Exports and Imports
  • Default Exports and Imports

Chapter 17:

Compiling typescript to javascript.

  • Compiling to JavaScript
  • Compiler Options

Chapter 18:

Es2015 and typescript.

  • What We'll Cover Next

Chapter 19:

Let and const in typescript.

  • let and const
  • TypeScript Considerations

Chapter 20:

  • Enhanced Object Literals
  • Shorthand for property names
  • Shorthand for method names
  • Computed property names

Chapter 21:

  • Destructuring Assignment
  • Destructuring Arrays
  • Destructuring Objects

Chapter 22:

  • Nested Destructuring

Chapter 23:

  • Spread Operator
  • Spreading Arrays
  • Spreading Objects

Chapter 24:

Object oriented typescript.

  • OOP Concepts in TypeScript
  • Encapsulation
  • Information Hiding

Chapter 25:

Inheritance and composition.

  • Inheritance and Composition in TypeScript
  • Benefits of Inheritance
  • Where Inheritance Fails
  • Favor Composition

Chapter 26:

Abstraction and polymorphism.

  • Abstraction with Interfaces
  • Using Polymorphism
  • Understanding Abstract Classes

Chapter 27:

Object oriented in practice with bufferunderflow.

  • Code Examples
  • Unique Entity
  • getUniqueId
  • Summary Interface
  • Using the Interfaces

Chapter 28:

Building attachment and image for bufferunderflow.

  • Modeling Attachment and Image
  • Defining Attachment
  • Defining the Image
  • Using ImageFormat
  • Understanding static
  • Building a Summary with getSummary
  • Completed Image Code
  • Using Image

Chapter 29:

Building the user model.

  • Adding Questions and Answers
  • Getting the SUmmary
  • Permissions
  • The Finished User
  • Using the User model

Chapter 30:

Building the question and answer models.

  • Modeling Question and Answer
  • Building the Answer Model
  • Generating a Summary
  • Improving addAnswer
  • Adding Private Setters
  • Completed Answer Class
  • Defining the Question Class
  • Setting Answers

Chapter 31:

Running bufferunderflow.

  • The Simulation Code
  • Conclusion and Review

Chapter 32:

Introduction to typescript and node.js.

  • Working With The File System
  • Configuring Development Environment
  • Building fs-json
  • Typed JSON files
  • Express and TypeScript

Chapter 33:

Building a typescript and node.js app.

  • Building number-app
  • The html file
  • Serving the HTML
  • Trying it out
  • Building NumInfo
  • Adding a new route
  • Handling Form Submissions
  • Using fetch

Chapter 34:

Where to go from here.

  • TypeScript and React
  • TypeScript and Angular
  • TypeScript and GraphQL
  • Let us know what you think!

Chapter 35:

  • Discussion 0

This page is a preview of Beginners Guide to TypeScript

Start a new discussion. All notification go to the author.

  • DSA with JS - Self Paced
  • JS Tutorial
  • JS Exercise
  • JS Interview Questions
  • JS Operator
  • JS Projects
  • JS Examples
  • JS Free JS Course
  • JS A to Z Guide
  • JS Formatter
  • TypeScript Indexed Access Types
  • Typescript Keyof Type Operator
  • TypeScript Omit<Type, Keys> Utility Type
  • TypeScript Pick<Type, Keys> Utility Type
  • What is readonly in Typescript ?
  • TypeScript Array slice() Method
  • TypeScript Array concat() Method
  • TypeScript Array some() Method
  • TypeScript | Array shift() Method
  • TypeScript | Array filter() Method
  • TypeScript | Array every() Method
  • TypeScript | String Length Property
  • TypeScript String Prototype Property
  • TypeScript | toPrecision() Function
  • TypeScript | toLocaleString() Function
  • TypeScript | toString() Function
  • TypeScript String
  • TypeScript Ambients Declaration
  • Classes in TypeScript

What is Parameter Destructuring in TypeScript ?

Parameter destructuring in TypeScript is a way to extract values from objects or arrays passed as function parameters, making it easier to work with their properties or elements directly within the function body.

There are several methods through which parameter destructuring is achieved in TypeScript which are as follows:

Table of Content

Object Destructuring

Array destructuring, rest parameters, default values.

When we’re working with objects, we can destructure the object directly within the function parameters. This is useful when we want to extract specific properties from the object.

Example: A function `printUser` logs the name and age of a user object, defined with name “Alice” and age 25, passed to it.

If one function receives an array as a parameter, we can destructure the array directly within the function parameters. This allows us to extract specific elements from the array.

Example: A function `printValues` extracts two values from an array of numbers and logs them. An array `[10, 20]` is defined and passed to the `printValues` function, printing “Value 1: 10, Value 2: 20” to the console.

Rest parameters in TypeScript allow functions to accept an indefinite number of arguments as an array. Think of them like a catch-all bucket for any extra arguments we might pass to a function. Instead of specifying every possible argument individually, we can use the rest parameter syntax, which is represented by three dots (…) followed by the name of the parameter. This lets you gather up any remaining arguments into an array, making your function more flexible and capable of handling varying numbers of inputs.

Example: A function `sum` calculates the sum of multiple numbers, including a first number followed by an arbitrary number of additional numbers. The function is called with parameters `1, 2, 3, 4, 5`, resulting in the sum `15` logged to the console.

TypeScript allows us to provide default values for destructured parameters. This is useful when we want to provide values if a property or element is missing.

Example: The`greet` function logs a greeting message, defaulting to “Bishal Paul” if no name is given. It’s called twice, first without a name and then with “GeeksforGeeks”.

Please Login to comment...

Similar reads.

author

  • Web Technologies
  • Google Introduces New AI-powered Vids App
  • Dolly Chaiwala: The Microsoft Windows 12 Brand Ambassador
  • 10 Best Free Remote Desktop apps for Android in 2024
  • 10 Best Free Internet Speed Test apps for Android in 2024
  • 30 OOPs Interview Questions and Answers (2024)

Improve your Coding Skills with Practice

 alt=

What kind of Experience do you want to share?

IMAGES

  1. TypeScript: How to Perform Object Destructuring with Types

    typescript destructuring assignment with type

  2. How to do object destructuring with types in TypeScript?

    typescript destructuring assignment with type

  3. TypeScript: Array Destructuring Assignment

    typescript destructuring assignment with type

  4. Object destructuring in TypeScript

    typescript destructuring assignment with type

  5. How to do object destructuring with types in TypeScript?

    typescript destructuring assignment with type

  6. Object destructuring with types in TypeScript

    typescript destructuring assignment with type

VIDEO

  1. Frontend Development Using React: Destructuring Assignment

  2. 財 Dee from Javascript to Typescript: 012 destructuring array

  3. Typescript Assignment-3-Type a simple message on screen

  4. Destructuring Assignment in JS #coding #javascript #javascripttutorial #shorts #short #shortvideo

  5. Destructuring in TypeScript/JavaScript

  6. 13 Destructuring via rest elements

COMMENTS

  1. typescript

    It is what is usually called a "deconstructing assignment pattern". What you are seeing here is actually a special TypeScript feature which allows types of be associated with such patterns. ... Typescript array destructuring type. 0. Typescript: Why destructuring an object doesn't hold type?

  2. Object destructuring with types in TypeScript

    There are two ways to do this: This tells TypeScript that the object you are destructuring has two properties, name and age, and they are both of type string and number respectively. name: string; age: number; } const { name, age }: Person = person; This tells TypeScript that the object you are destructuring conforms to the Person interface ...

  3. Object destructuring with types in TypeScript

    I am familiar with TypeScript basics but sometimes I hit a problem. Object destructuring was one of those. I wanted to do. const { name, age } = body.value. I tried adding the string and number types like this: const { name: string, age: number } = body.value. But this didn't work. It apparently worked, but in reality this is assigning the ...

  4. TypeScript: Documentation

    This is especially true with deeply nested destructuring, which gets really hard to understand even without piling on renaming, default values, and type annotations. Try to keep destructuring expressions small and simple. You can always write the assignments that destructuring would generate yourself. Spread

  5. TypeScript: Destructuring Objects with Types

    TypeScript: Destructuring Objects with Types Learn the simple yet effective way to destructure objects with type annotations in TypeScript. This post breaks down the common pitfalls and provides a clear guide to using types with object destructuring, making your TypeScript code cleaner and more reliable.

  6. Destructuring Object parameters in TypeScript functions

    The code for this article is available on GitHub. Unfortunately, when destructuring parameters in TypeScript functions, we have to repeat the properties when typing them. The first example shows how to destructure the name and age properties of an object parameter. index.ts. function getPerson({ name, age }: { name: string; age: number ...

  7. How to do object destructuring with types in TypeScript?

    Sometimes when you destructure object properties in TypeScript, you may want to define the type for the property you are destructuring. TL;DR // an object const John = { age: 23, isAdult: true, }; // get age property using destructuring syntax // and set the type of age property const { age }: { age: number} = John; . For example, let's say I have an object called John with some properties ...

  8. Typing Destructured Object Parameters in TypeScript

    Because TypeScript is a superset of JavaScript, every valid JavaScript file is a valid TypeScript file (set aside type errors, that is). Therefore, TypeScript can't simply change the meaning of the destructuring expression { pretty: boolean }. It looks like a type annotation, but it's not. #Typing Immediately Destructured Parameters. Of course ...

  9. 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.

  10. Understanding TypeScript Destructuring: A Comprehensive Guide

    Destructuring Arrays; Basic Array Destructuring; The most basic form of destructuring is array destructuring. Consider an array of two numbers. Normally, to assign these numbers to their own variables, you would have to do something like this: let arr = [1, 2]; let a = arr[0]; let b = arr[1]; With destructuring, this can be simplified to:

  11. ES6 Destructuring In Depth When Using TypeScript

    To work around this, we have the destructuring assignment introduced in ES6: The same code using destructuring. That's a lot more concise. And notice how we're setting the value for id . When ...

  12. ES6 Destructuring in TypeScript. A quick look at ES6 ...

    TypeScript is then able to understand that the function takes an object argument that is of the shape of the Person interface and destructuring occurs as you would expect it to in ES6. This ...

  13. Specify TypeScript Types for Destructured Object Properties

    You can simply specify the type of an object you're destructuring after : . The type can either be specified inline, or from an existing interface, type declaration, or by using type assertions. Infer Types From Object's Type Declaration Ideally, you should correctly type the object wherever possible because if the object itself has a type declaration, then TypeScript would infer those types ...

  14. Object destructuring in TypeScript

    By using this destructuring, we extract specific properties from an object. But how do we now define the types for this destructured object? TypeScript casting a destructured object type permalink. You might immediately think the following will work: const { firstname: string, age: number} = user;

  15. Using Object Destructuring to Assign Class Members

    return Object.getOwnPropertyNames(this).map(key => ({[key]: this[key]})); You can use Object.assign (es5+), as suggested by Frank, or Object.defineProperty to initialize the member fields in the constructor. The latter gives the option to make the properties writable or assign getters and/or setters.

  16. typescript

    Script: string, EstimatedDuration: number, ActualDuration: number. } = responseObject; console.log(script, estimated_duration, actual_duration); At that point though you're just writing the actual type declaration, so you could also make that type below an interface somewhere for easy access. answered May 31, 2018 at 0:29.

  17. Argument Destructuring and Type Annotations in TypeScript

    And you can thank Anders Hejlsberg for his super quick answer. You can add top level type annotations like this: function say( { something = 'hello world 1' }: { something: string } = { something: 'hello world 2', } ) { console.log(something) } Which works just as you would expect and gives you type annotations with type safety and nice ...

  18. Strongly-typed destructuring and rest parameters

    Destructuring assignment and rest parameters are awesome and typical in codebases these days. Is it possible to strongly-type these though in TypeScript? Let's find out. TypeScript has tuples. Before we figure out how to strongly-type rest parameters, let's understand tuples. A tuple can be thought of as an array with a fixed number of ...

  19. Destructuring Assignment

    Destructuring Assignment - Beginners Guide to TypeScript | newline. Extracting data from objects and arrays is among the most common operations in JavaScript. Destructuring gives us a concise syntax for extracting data and saving it to variables.

  20. What is Parameter Destructuring in TypeScript

    Parameter destructuring in TypeScript is a way to extract values from objects or arrays passed as function parameters, making it easier to work with their properties or elements directly within the function body.. There are several methods through which parameter destructuring is achieved in TypeScript which are as follows:

  21. javascript

    Just declare the type on the variable, without that weird object notation: const { ...foo }: TYPE = e; That is a weird way to make a copy of an object however - it's usually done like so:

  22. angular

    You can do it with the following syntax: ({ prop: this.prop } = obj); Here I'm using a deep object matching. var obj = { propIwantFromObj: 'foo' }; var { propIwantFromObj: whereToStoreValue } = obj; On the left part you will say which property you want to get from the object and on the right side you are going to say where to store the value.