Namespaces are just fine

Published 6/13/2022

An increasingly common practice in JavaScript is destructuring. This is great to get rid of otherwise generic terms like in the following examples.

Destructuring objects:

/*❌*/ const results = await fetch('users')
/*❌*/ results.users
/*✔️*/ const { users } = await fetch('users')

Destructuring arrays:

/*❌*/ const results = await validate(request)
/*❌*/ if (!results[0]) throw results[1]
/*✔️*/ const [isSuccessful, error] = await validate(request)
/*✔️*/ if (!isSuccessful) throw error

These are very good use-cases for destructuring!

But then there is the other side of the coin:

const { user: { city }} = results

The variable “city” had a perfect home with the namespace “user”. It’s very clear that “user.city” is the city belonging to the user. With the nested destructuring technique, you lose these benefits.


This overdestructuring can also lead to name clashes, which would require renaming the variable:

const { city } = location
const { user: { city: userCity }} = results

“userCity” vs. “user.city”. Is this difference worth the added complexity and loss of intent?

Compare these two code statements that could follow the above example:

/*❌*/ if (city === userCity) {}
/*✔️*/ if (location.city === user.city) {}

In multi-line statements, over-destructuring can also confuse the reader as to which side of the assignment the reader is currently on (left side or right side):

const {
  user: {
    city: userCity
  },
  location: {
    city: locationCity
  }
  ...rest
} = {
  ...cache,
  user: await getUser()
  date: now()
}

Not enough? How about some inlined TypeScript types to mix things up:

const {
  user: {
    city: userCity
  },
  location: {
    city: locationCity
  }
  ...rest
} = {
  ...cache,
  user: await getUser()
  date: now()
} : {
  user: {
    id: string;
    city: string
  }
  date: number,
  location: {
    id: string;
    city: string;
  }
}

Namespaces are just fine. In fact, they are very helpful in communicating where a variable belongs to. And best of all, you get all of it out of the box.


This was an excerpt from my e-book Intent-Driven Development which will teach you how to simplify the day-to-day code you run into and the balance between over- and under-engineering. Get it over at https://michaelzanggl.com/intent.