Functions and generics
Object destructuring with types in TypeScript
Learn the correct TypeScript syntax for adding types to object destructuring, why name: string fails, and how a dedicated type or interface keeps it clean.
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
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 name property to the string variable, and the age property value to the number variable.
That is because a colon inside a destructuring pattern already has a meaning in JavaScript: renaming. { name: string } means “take the name property and put it in a variable called string”. No error, no types, just two badly named variables. That is why the mistake is sneaky — the code runs.
The correct syntax is this:
const { name, age }: { name: string; age: number } = body.value
The annotation goes after the whole pattern, and it types the object being destructured, not the individual variables. TypeScript then works out that name is a string and age is a number from the object type.
The best way to approach this would be to create a type or interface for that data:
interface Dog {
name: string
age: number
}
Then you can write the above in this way, which is shorter:
const dog: Dog = body.value
And once the value is typed, destructuring needs no annotation at all:
const { name, age } = dog
TypeScript already knows the shape of dog, so name and age get their types by inference. This is the version I end up with most of the time: type the value once, destructure freely afterwards.
The same pattern-then-annotation syntax works in function parameters, where destructuring is common:
function describeDog({ name, age }: Dog) {
return `${name} is ${age} years old`
}
Again the type applies to the whole parameter object, and the destructured variables are inferred from it.
Lesson completed