Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Guide section 5.1 on object destructuring may lead to anti-pattern #2619

Open
pedropedruzzi opened this issue Jul 26, 2022 · 3 comments
Open

Comments

@pedropedruzzi
Copy link

This issue is realted to guide section 5.1 Use object destructuring when accessing and using multiple properties of an object

Although the section rationale and examples are very clear and logical, IMO when followed unrestrictedly (or naively) it may lead to an anti-pattern with the bad features this very section is trying to avoid in the first place (repetitive code, opportunities for mistakes and unnecessary extra temporary references).

Apparently the anti-pattern arises more clearly when there is a combination of these conditions:

  • Accessed object properties have meaningful names and are each only referenced once, thus not requiring local variables.
  • There are more than a handful of accessed properties
  • The accessed properties are mostly used to create a new object, with or without key/value transformations

Here's an example to illustrate:

// bad
function toNewUserType(user) {
  const {
    id: userId,
    status: userStatus,
    email,
    phone,
    encryptedPassword,
    firstName,
    middleName,
    lastName,
    jobTitle,
    birthDate,
    createdAt,
    updatedAt,
    address,
  } = user;

  return {
    userId,
    userStatus,
    email,
    phone,
    encryptedPassword,
    jobTitle,
    birthDate,
    createdAt: toDate(createdAt),
    updatedAt: toDate(updatedAt),
    address: toNewAddressType(address),
    userHash: idToHash(userId),
    fullName: getFullName(firstName, middleName, lastName),
  };
}

// still bad
function toNewUserType({
  id: userId,
  status: userStatus,
  email,
  phone,
  encryptedPassword,
  firstName,
  middleName,
  lastName,
  jobTitle,
  birthDate,
  createdAt,
  updatedAt,
  address,
}) {
  return {
    userId,
    userStatus,
    email,
    phone,
    encryptedPassword,
    jobTitle,
    birthDate,
    createdAt: toDate(createdAt),
    updatedAt: toDate(updatedAt),
    address: toNewAddressType(address),
    userHash: idToHash(userId),
    fullName: getFullName(firstName, middleName, lastName),
  };
}

// good
function toNewUserType(user) {
  return {
    userId: user.id,
    userStatus: user.status,
    email: user.email,
    phone: user.phone,
    encryptedPassword: user.encryptedPassword,
    jobTitle: user.jobTitle,
    birthDate: user.birthDate,
    createdAt: toDate(user.createdAt),
    updatedAt: toDate(user.updatedAt),
    address: toNewAddressType(user.address),
    userHash: idToHash(user.id),
    fullName: getFullName(user.firstName, user.middleName, user.lastName),
  };
}

If the package owners agree with the problem, I believe we should be able to add some content to warn about this anti-pattern and how to avoid it.

Thanks in advance.

@ljharb
Copy link
Collaborator

ljharb commented Jul 26, 2022

I’m not sure this is an antipattern, given the language features available to us.

Just because there’s repetition doesn’t automatically mean it’s bad - it would be nice to reduce it, but in your last example, user is repeated many many times. The repetition of de and re structuring is imo much better than the repetition of the object.

@pedropedruzzi
Copy link
Author

pedropedruzzi commented Jul 26, 2022

I agree with "Just because there’s repetition doesn’t automatically mean it’s bad". This issue is really to raise this discussion of whether or not this is an antipattern (should be marked with "question" label?). So thanks for your input!

I disagree on your assessment on the two types of repetition though. Mostly because the user.field repetition is purely syntactical (a future language feature may even remove its need - e.g. a new object to object assignment with a syntax similar to destructuring) and limited to a single line per property. Whereas the de/re structuring requires two non-contiguous lines per property and, as with any "regular" case of duplication, there are more opportunities for mistakes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants
@ljharb @pedropedruzzi and others