@senocular and @aleen42, I am convinced. I saw pick and omit as more symmetrical operations to each other, but it makes more sense to not ignore the prototype chain.
You could start by using https://github.com/tc39/template-for-proposals to make a proposal repo. Clearly outlining the problem first and foremost, discussing prior art and userland solutions, discussing current alternatives, and then discussing a proposed solution would go a long way towards convincing a delegate to champion it.
If you treat pick as a similar problem as array slicing, it makes sense that it would have a dedicated syntax for it similar to this proposal: GitHub - tc39/proposal-slice-notation
Something like
let full = { a: 1, b: 2, c: 3 }
let part = full.{a,b} // { a: 1, b: 2 }
Though I would rather have both a pick() function and a pick syntax, and have the function version support dynamic keys while the syntax version does not. I don't think dynamic keys is a common enough use case for the added syntax baggage.
Unfortunately, that would make o.[a, b] very different from o?.[a, b] and o[a, b]
(just to be clear I think comma should not be an operator there, but sadly it is).
You could drop the superfluous . in-between and just use ... to distinguish slicing from indexing:
({a : 1, b : 2, c : 3})[...['a', 'b']]; // => {a : 1, b : 2}
const keys = ['a', 'b'];
({a : 1, b : 2, c : 3})[...[keys[0]]]; // => {a : 1}
({a : 1, b : 2, c : 3})[...keys]; // => {a : 1, b : 2}
That "expect" is clearly wrong, nothing confusing about it. I said remove the dot outside and use 3 inside instead. You omitted the dots inside, of course that's plain old indexing.
Just to clarify, are you two (@lightmare and @aleen42) proposing these bracket syntaxes in addition to the full.{a, b} syntax that @jamiebuilds proposed? Or in place of? I presume it's in place of?
I'm going to make a couple of arguments in favor of @jamiebuilds's syntax:
It's built for the most common use case of just picking pre-known properties off of an object. You don't have to use strings (but we can still add support for dynamic key if wanted. Similar to how object literals and destructuring are built for the most common use case of non-dynamic keys, but have support for dynamic keys)
It could be extended to support other nice features, such as renaming while picking the properties off, or setting default values if the properties don't exist. Hopefully, you can see a parallel with object destructuring. With object destructuring, we pick properties off and put them in the local namespace. With this pick syntax, we pick properties off and put them in a new object.
It's actually got a minor prior art in Microsoft's Bosque language as well (see here), which has an object pick syntax that's exactly the same.
(I've actually started a thread in the past which suggested having this kind of syntax here, which is why I like it so much)
// pick a, b, and c off
// if b doesn't exist, set it to 2
// rename c to C
const newObj = oldObj.{ a, b = 2, c: C }
// Example of dynamic keys
// (again, do you see the parallel with object destructuring?)
const anotherNewObj = something.{ x, [key1], [key2]: renamedKey }