Shorthand object initializer syntax for matching property name

Viewed 187

Sometimes I find myself needing to initialize an object with a property that matches the property of another object. When the property name is the same, I want to be able to use shorthand syntax.

(For the purposes of the examples in this question, I'll just keep the additional properties to a tag: 1 property, and I'll reuse message in subsequent examples as the input/source of the information. I also indicate an extra unwanted property of message because I'm cherry-picking properties and do not intend to just use Object.assign to assign all the properties of message to the result.)

const message = {
  person: {
    name: 'John'
  },
  unwanted: 'x'
};

let result = { person: message.person, tag: 1 };  // Looking for shorthand for this

To formulate the result object above, I needed to type person twice. I was thinking there must be a shorthand way to do this. My reasoning for expecting this to work is that features exist like ES2015 Shorthand property names and Destructuring assignment. e.g:

const { person } = message;  // destructing assignment
let result = { person, tag: 1 };  // shorthand property name for `person`

This would create an extra variable called person that has the value of message.person, And the result would have a property called person that has the desired value. But if there's no variable already existing then I don't know how to use shorthand in this case. And I haven't found a way to apply these two syntactical features together.

This was my first intuitive guess at what the syntax would be:

// hoping destructuring assignment is allowed in object literal
let result = { {person} = message, tag: 1 };  // it is not legal :(

My second guess was this:

// hoping that a property name would magically be inferred from `person`
let result = { message.person, tag: 1 };  // it is not legal :(

As a last resort I tried Object.assign, but it copies unwanted properties and does not cherry-pick just the person property of message.

let result = Object.assign({ tag: 1 }, message);  // Assigns unwanted properties :(

So the best I have so far is { person: message.person, tag: 1 }

Is there shorthand initializer syntax to achieve this?

2 Answers

The best I have so far is { person: message.person, tag: 1 }.

Is there shorthand initializer syntax to achieve this?

No, this is still they way to go.

hoping that a property name would magically be inferred from person

let result = { message.person, tag: 1 };

There is the ECMAScript Shorthand Property Assignment Improvements proposal that would allow exactly this. Unfortunately, it's still at stage 0 :-/

Assuming you're using ES6:

const message = {
  person: {
    name: 'John'
  },
  unwanted: 'x'
};

let { unwanted, ...result } = { ...message, tag: 1 };

console.log(result);

If you'd like to rename the unwanted variable to something then to dit

let { unwanted: dummy, ...result } = { ...message, tag: 1 };

These have some issues, e.g

  • This creates an extra variable unwanted (or dummy if you use the 2nd approach)
  • If you have multiple unwanted properties, you have to write them all in the destructuring

So in my opinion, you're better off to go with the way you described in your question already.

Related