proposal-deep-path-properties-for-record icon indicating copy to clipboard operation
proposal-deep-path-properties-for-record copied to clipboard

Less obtrusive approach for deep paths

Open stiff opened this issue 4 years ago • 7 comments

Currently [] is used to support dynamic properties, with simple extension like this:

const obj = { ['a', 'b' ]: 5};

we can enable full support for dynamic paths, both static and dynamic, and make it explicit that it is a path, not an expression a.b.

This also would resolve #11 , #16 and #17

stiff avatar Jan 23 '21 09:01 stiff

This already has semantics: it’s a comma operator, resolving to “b”, in a computed property.

ljharb avatar Jan 23 '21 14:01 ljharb

Latest chrome doesn't agree with you:

{ ['a', 'b']: 5 }
VM417:1 Uncaught SyntaxError: Unexpected token ':'
const obj = { ['a', 'b']: 5 }
VM438:1 Uncaught SyntaxError: Unexpected token ','

stiff avatar Jan 23 '21 16:01 stiff

ah, you're right - ({ [('a', 'b')]: 5 }) works, however - so your suggestion would mean the difference between the comma operator and deep paths is "parens", which seems a bit close for comfort.

ljharb avatar Jan 23 '21 17:01 ljharb

Do you have an idea how nobody ever managed to run into this issue with arrays, which look and work exactly same as I propose? :)

[1,2]
> [1, 2]

[(1,2)]
> [2]

I see no problem that square brackets [] mean array(-ish). Following this logic scales nicely to

const arr = ['a', 3, 'b'];
obj[...arr] == obj[arr[0]][arr[1]][arr[2]] == obj.a[3].b

stiff avatar Jan 23 '21 17:01 stiff

I had the same idea when I saw the proposal's syntax.

  • This has the benefit of familiarity given its a clear extension of the existing dynamic key syntax, as well as its similarity to Immutable-style code.
  • It's also much clearer which things are part of the path and which are part of the value, since you have the brackets to visually help.

I also really like the idea you hint at here:

const arr = ['a', 3, 'b'];
obj[...arr] == obj[arr[0]][arr[1]][arr[2]] == obj.a[3].b

where you could spread an actual array of values. The other syntax has no way to perform this very useful action.

cypherfunc avatar Aug 19 '21 22:08 cypherfunc

I like the idea generally, but there is an issue, o = {[key]: v} correspond to o[key] = v, so if we have o = {[key1, key2]: v}, it should correspond to o[key1, key2] = v, but even {[key1, key2]: v} is possible, o[...keys] is also possible, o[key1, key2] = v is not (as @ljharb mentioned).

I feel we might regret about the comma expressions... Theoretically we could investigate whether change the semantic of o[a, b] would really break the web, if not, we could fix it (like let[x] = v in ES6 break ES5-, but we still land it), but I suspect browser vendors would willing to do such investigation.

A possible compromising is using linter forbid o[a, b] and autofix it to o[...[a, b]]. Though I always think let new language feature rely on linter is so bad, should be the last resort (because adopting linter and new rules always have very large ecosystem/community cost).

Another possible solution is changing the syntax slightly. Instead of { [k1, k2]: v }, use { .[k1, k2]: v }. We can also introduce o.[k1, k2] = v if we like. Essentially, o.[...] is just the fixed version of o[...]. Prefix dot make it much explicit that [...] is actually a tuple for deep path. Such syntax also somehow increase the consistency with o?.[...].

hax avatar Jan 15 '22 03:01 hax

It absolutely would break the web; comma expressions can't ever be changed. Tons of minifiers use that syntax.

ljharb avatar Jan 15 '22 03:01 ljharb