DEV Community

Cover image for Supporting choiceful (object and array) destructuring in JavaScript and TypeScript
Michał Gacka for 3dayweek.dev

Posted on • Edited on

Supporting choiceful (object and array) destructuring in JavaScript and TypeScript

The joy of object and array destructuring is most likely known to you (check out an example below if it's not 🙂). But what about the joy of being able to choose between them while using the same function? How exciting would that be!?

Wait, but why? Well, because each has its upsides and there is usually no good enough reason to force the developer to use one of them by design. Array destructuring allows you to more succinctly rename the variables but requires remembering the order, while object destructuring forces you to remember the name but doesn't mind the order.

What are object and array destructuring?

// object destructuring
const o = {
  firstN: 'Plants',
  v: 'need',
  secondN: 'water'
}
const {firstN, secondN} = o;
console.log(secondN); // water

// array destructuring
const a = ['Plants', 'need', 'water'];
const [firstNoun, verb] = a;
console.log(firstNoun); // Plants
Enter fullscreen mode Exit fullscreen mode

They are a succinct way to retrieve variables from a more complex type. Easy to use and easy to read. If used adequately. And in order to maximize the chance that they are indeed used correctly, you might want to defer the choice for which one to use by allowing both when returning from your functions. Just like the useInView() React Hook did which inspired me to write this.

First in pure JavaScript:

const veryImportantSelfContainedLogic = (n) => {
  const result = ['Plants', 'need', n, 'waters'];

  result.firstWord = result[0];
  result.anotherWord = result[1];
  result.notAWord = result[2];
  result.lastWord = result[3];

  return result;
};
Enter fullscreen mode Exit fullscreen mode

And then in TypeScript (highly recommended if you haven't made the transition yet):

type VeryImportantSelfContainedLogicResponse = [string, string, number, string] & {
  firstWord: string;
  anotherWord: string;
  notAWord: number;
  lastWord: string;
};

const veryImportantSelfContainedLogic = (
  n: number = 5
): VeryImportantSelfContainedLogicResponse => {
  const result = ['Plants', 'need', n, 'waters'] as VeryImportantSelfContainedLogicResponse;

  result.firstWord = result[0];
  result.anotherWord = result[1];
  result.notAWord = result[2];
  result.lastWord = result[3];

  return result;
};
Enter fullscreen mode Exit fullscreen mode

The developer using your function can then choose which type of restructuring to use depending on their mood (or some other considerations if one finds them more important):

// decided to rename the second variable in comparison to the function author's intention
const [firstWord, secondWord] = veryImportantSelfContainedLogic(3); 

// has to follow the naming
const {firstWord, anotherWord} = veryImportantSelfContainedLogic(5);

// or redefine it like so
const {firstWord, anotherWord: secondWord} = veryImportantSelfContainedLogic(5);
Enter fullscreen mode Exit fullscreen mode

Neat, isn't it? ☀️

Let me know in the comments if you see any downsides in supporting choiceful destructuring by default or if you're all in on the idea 🤓

Top comments (0)