62

There are already a lot of cool features in ES6/ES7 for defining Javascript objects. However, the following pattern is common in Javascript:

const obj = { 
  requiredKey1: ..., 
  requiredKey2: ... 
};

if (someCondition) { 
  obj.optionalKey1 = ...;
}

Is there a way to define the object all at once with both optional and required keys?

Andrew Mao
  • 31,800
  • 17
  • 126
  • 212
  • Why not just use a ternary? `optionKey1: someCondition ? value : undefined`? – Andrew Li Dec 19 '17 at 17:21
  • @FelixKling I think that's a largely theoretical distinction because there is not a 'whole' ES6 or ES7 standard implemented in Node/browser environments and most people are using transpilers anyway. – Andrew Mao Dec 20 '17 at 18:49
  • 1
    Well, it defines the scope for answers. We don’t know what you are using. Also I don’t want people to misuse the term ES7 for experimental features. – Felix Kling Dec 20 '17 at 18:53
  • 1
    @FelixKling I'm asking about any standard of Ecmascript; obviously existing supported standards is better. If this can be done with experimental features, okay. If it can be done with ES6 or ES7, better. If it is possible with ES5, super! – Andrew Mao Dec 20 '17 at 18:55
  • 3
    I would love to see something like `{ key?: optionalValue }` or with property shorthand: `{ optionalValue? }` – cimak Nov 14 '20 at 23:31

3 Answers3

145

You can use object spread to have an optional property.

Note: Object Rest/Spread is a stage 4 proposal for ECMAScript. You might need the babel transform to use it.

let flag1 = true;
let flag2 = false;

const obj = { 
  requiredKey1: 1, 
  requiredKey2: 2,
  ...(flag1 && { optionalKey1: 5 }),
  ...(flag2 && { optionalKey2: 6, optionalKey3: 7 }),
  ...(flag1 && { optionalKey4: 8, optionalKey5: 9 })
};

console.log(obj);
Ori Drori
  • 145,770
  • 24
  • 170
  • 162
5

To indicate optional key, you can assign to it null, if the condition is false

const someCondition = true;

const obj = { 
  requiredKey1: 1, 
  requiredKey2: 2,
  optionalKey1: someCondition ? 'optional' : null
};

console.log(obj);
Suren Srapyan
  • 57,890
  • 10
  • 97
  • 101
  • 12
    Good answer, but worth noting that by doing this, `optionalKey1` still appears as one of the keys of the object if the condition is false (and has the value null), whereas OPs original snippet will create an object that lacks the key entirely if the condition is false. – CRice Dec 19 '17 at 17:32
  • I think, assigning `null` to the property is more understandable that it is optional and does not have value than checking for the existence – Suren Srapyan Dec 19 '17 at 17:53
  • 1
    I personalyl would like to get some sort of error, and generally whatever behavior a language (and JavaScript in particular) would give me when trying to access an inexistent property, rather than making it nullable, since it's *not ever* going to have a value, unlike what nullable values are used for - it it needs to exists, it exists. If it doesn't need to exits, it doesn't - I think that makes more sense. – Gal Grünfeld Dec 01 '20 at 18:39
-2

the following pattern is common in Javascript

It should not. Having many objects of different shapes can incur a performance penalty. Records should always contain the same keys. So just use

const obj = { 
  requiredKey1: …, 
  requiredKey2: …,
  optionalKey1: someCondition ? … : undefined,
};
Bergi
  • 513,640
  • 108
  • 821
  • 1,164
  • The pattern is really useful in objects you pass as options. – krulik Dec 10 '19 at 10:24
  • 2
    @krulik Option object parameters usually can deal totally fine with `undefined` properties, not distinguishing them from non-existing properties. – Bergi Dec 10 '19 at 11:56