Skip to content
This repository has been archived by the owner on Feb 19, 2018. It is now read-only.

CS2 Discussion: Features: Support splats in object literals (object rest/spread syntax) #66

Closed
connec opened this issue Dec 15, 2016 · 9 comments

Comments

@connec
Copy link

connec commented Dec 15, 2016

I would love to see object spreads and rests supported via splats in object literals:

{ foo, rest... } = { foo: 1, bar: 2 }
console.log foo, rest # 1 { bar: 2 }
console.log { foo, rest... } # { foo: 1, bar: 2 }

obj = { foo: 1 }
copy = { ...obj }
console.log obj === copy # false

setName = (name, record) -> { name, record... }
console.log setName 'greeting', hello: 'world' # { name: 'greeting', hello: 'world' }

stripName = ({ name, record... }) -> record
console.log stripName name: 'greeting', hello: 'world' # { hello: 'world' }

Compilation in the 2 branch could happily use Object.assign for construction:

// console.log { foo, rest... }
console.log(Object.assign({ foo }, rest))

Destructuring would require more implementation, e.g.

// { foo, rest... } = { foo: 1, bar: 2 }
var ref, ref1, ref2, i, k, foo, rest
ref = { foo: 1, bar: 2 }
ref1 = Object.keys(ref)
ref2 = [ 'foo' ] // compiler-generated list of the non-splat properties
foo = ref.foo
rest = {}
for (i = 0; i < ref1.length; i++) {
  k = ref1[i]
  if (ref2.indexOf(k) < 0) {
    rest[k] = ref[k]
  }
}

We could alternatively wait for the proposal to land in environments, or rely on a transpiler like babel.

@connec connec changed the title Splats in object literals Support splats in object literals (object rest/spread syntax) Dec 15, 2016
@JavascriptIsMagic
Copy link

I've been seeing object spread being recommended and I've seen it being used heavily in large production code bases. I find myself using Object.assign quite a bit myself in situations where I would have much cleaner code using object spread, and it is such a nice compliment to the array... spread


I think this does require you to use the {brackets} in the syntax or it will get ambiguous with the array... spread:

fun a: 1, b...   # ambiguous
fun {a: 1, b...} # unambiguous

Also do we go with the spec and put the operator on the left { ...spread } or go with coffeescripty { spread... } ?

One benefit to having it go in the opposite direction would be that it could disambiguate the two and we could get rid of the need for {brackets}

# object spread:
fun a: 1, ...b # fun({ a: 1, ...b })
# argument spread:
fun a: 1, b... # fun({ a: 1 }, ...b)

Though consistency of the spread syntax might be preferred over getting rid of ambiguity.

@connec
Copy link
Author

connec commented Dec 15, 2016

I'd definitely vote for consistency over that ambiguity, though it is an annoying one. Ultimately I suppose it's consistent with needing explicit braces to have shorthand objects in arguments lists too.

f a: a, b     # f({ a: a }, b)
f { a: a, b } # f({ a: a, b: b })

@YamiOdymel
Copy link

YamiOdymel commented Feb 22, 2017

I'd recommend to put the ... in front of the object, variable,

so you can spread an object from the function like this (This is very common in Vuex, Redux):

export default {
    name: 'CounterBlock'
    methods:
        ...mapActions
            increment : counter.actions.increment,
            set       : counter.actions.set,
            fetchCount: counter.actions.fetchCount
    computed:
        ...mapGetters
            total: counter.getters.total
}

currently with [email protected] there's no spread operator, so you would have to use Object.assign({}, obj1, obj2) instead.

export default {
    name: 'CounterBlock'
    methods: Object.assign {}, mapActions
            increment : counter.actions.increment,
            set       : counter.actions.set,
            fetchCount: counter.actions.fetchCount
    computed: Object.assign {}, mapGetters
            total: counter.getters.total
}

with ECMAScript6

export default {
    name: 'CounterBlock',
    methods: {
        ...mapActions({
            increment : counter.actions.increment,
            set       : counter.actions.set,
            fetchCount: counter.actions.fetchCount
        })
    },
    computed: {
        ...mapGetters ({
            total: counter.getters.total
        })
    },
}

@GeoffreyBooth
Copy link
Collaborator

Added via jashkenas/coffeescript#4493

@c5n8
Copy link

c5n8 commented Oct 14, 2017

@GeoffreyBooth @YamiOdymel
After #4493, how can we get below code now?

...mapActions({
  increment : counter.actions.increment,
  set       : counter.actions.set,
  fetchCount: counter.actions.fetchCount
})

@YamiOdymel
Copy link

@chabib Well, if I'm not mistaken, you could use it like this.

object = {
    ...mapActions
        increment : counter.actions.increment,
        set       : counter.actions.set,
        fetchCount: counter.actions.fetchCount
}

Which produces:

var object, _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

object = _extends({}, mapActions({
      increment: counter.actions.increment,
      set: counter.actions.set,
      fetchCount: counter.actions.fetchCount
}));

is the same as below with ECMAScript6

object = {
    ...mapActions({
        increment : counter.actions.increment,
        set       : counter.actions.set,
        fetchCount: counter.actions.fetchCount
    })
}

@c5n8
Copy link

c5n8 commented Oct 14, 2017

Thank you @YamiOdymel !
Looks like we can do this

export default
  computed: {
    ...mapActions
        increment : counter.actions.increment,
        set       : counter.actions.set,
        fetchCount: counter.actions.fetchCount
  }

But not this

export default
  computed:
    ...mapActions
        increment : counter.actions.increment,
        set       : counter.actions.set,
        fetchCount: counter.actions.fetchCount

@YamiOdymel
Copy link

@chabib I asked about this in jashkenas/coffeescript#4449

Keyless property requires explicit braces - {}.

@coffeescriptbot coffeescriptbot changed the title Support splats in object literals (object rest/spread syntax) CS2 Discussion: Features: Support splats in object literals (object rest/spread syntax) Feb 19, 2018
@coffeescriptbot
Copy link
Collaborator

Migrated to jashkenas/coffeescript#4959

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

No branches or pull requests

6 participants