diff --git a/packages/babel-plugin-transform-destructuring/src/index.js b/packages/babel-plugin-transform-destructuring/src/index.js index a38cfb6b38..9d58303612 100644 --- a/packages/babel-plugin-transform-destructuring/src/index.js +++ b/packages/babel-plugin-transform-destructuring/src/index.js @@ -170,7 +170,8 @@ export default declare((api, options) => { pushObjectRest(pattern, objRef, spreadProp, spreadPropIndex) { // get all the keys that appear in this object before the current spread - let keys = []; + const keys = []; + let allLiteral = true; for (let i = 0; i < pattern.properties.length; i++) { const prop = pattern.properties[i]; @@ -182,11 +183,15 @@ export default declare((api, options) => { // ignore other spread properties if (t.isRestElement(prop)) continue; - let key = prop.key; + const key = prop.key; if (t.isIdentifier(key) && !prop.computed) { - key = t.stringLiteral(prop.key.name); + keys.push(t.stringLiteral(key.name)); + } else if (t.isLiteral(key)) { + keys.push(t.stringLiteral(String(key.value))); + } else { + keys.push(t.cloneNode(key)); + allLiteral = false; } - keys.push(t.cloneNode(key)); } let value; @@ -196,11 +201,18 @@ export default declare((api, options) => { t.cloneNode(objRef), ]); } else { - keys = t.arrayExpression(keys); + let keyExpression = t.arrayExpression(keys); + + if (!allLiteral) { + keyExpression = t.callExpression( + t.memberExpression(keyExpression, t.identifier("map")), + [this.addHelper("toPropertyKey")], + ); + } value = t.callExpression( this.addHelper(`objectWithoutProperties${loose ? "Loose" : ""}`), - [t.cloneNode(objRef), keys], + [t.cloneNode(objRef), keyExpression], ); } diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/es7-object-rest-builtins/output.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/es7-object-rest-builtins/output.js index 8e8f967908..8dcd578573 100644 --- a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/es7-object-rest-builtins/output.js +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/es7-object-rest-builtins/output.js @@ -6,7 +6,7 @@ var _z2 = z, y = babelHelpers.objectWithoutProperties(_z2, ["x"]); var _z3 = z, x = _z3[x], - y = babelHelpers.objectWithoutProperties(_z3, [x]); + y = babelHelpers.objectWithoutProperties(_z3, [x].map(babelHelpers.toPropertyKey)); (function (_ref) { var x = _ref.x, diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/es7-object-rest-loose/output.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/es7-object-rest-loose/output.js index 50093aa172..4351f25743 100644 --- a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/es7-object-rest-loose/output.js +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/es7-object-rest-loose/output.js @@ -1,3 +1,5 @@ +function _toPropertyKey(key) { if (typeof key === "symbol") { return key; } else { return String(key); } } + function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } function _extends() { _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; }; return _extends.apply(this, arguments); } @@ -13,7 +15,7 @@ var _z2 = z, var _z3 = z, x = _z3[x], - y = _objectWithoutPropertiesLoose(_z3, [x]); + y = _objectWithoutPropertiesLoose(_z3, [x].map(_toPropertyKey)); (function (_ref) { let x = _ref.x, diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/es7-object-rest/output.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/es7-object-rest/output.js index 0729c49dd0..c4af22047a 100644 --- a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/es7-object-rest/output.js +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/es7-object-rest/output.js @@ -6,7 +6,7 @@ var _z2 = z, y = babelHelpers.objectWithoutProperties(_z2, ["x"]); var _z3 = z, x = _z3[x], - y = babelHelpers.objectWithoutProperties(_z3, [x]); + y = babelHelpers.objectWithoutProperties(_z3, [x].map(babelHelpers.toPropertyKey)); (function (_ref) { var x = _ref.x, diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/function-key-with-object-rest-spread/exec.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/function-key-with-object-rest-spread/exec.js new file mode 100644 index 0000000000..fc8ae90c74 --- /dev/null +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/function-key-with-object-rest-spread/exec.js @@ -0,0 +1,4 @@ +const { [(() => 1)()]: a, ...rest } = { 1: "a" }; + +expect(a).toBe("a"); +expect(rest).toEqual({}); diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/function-key-with-object-rest-spread/options.json b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/function-key-with-object-rest-spread/options.json new file mode 100644 index 0000000000..9fd3882905 --- /dev/null +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/function-key-with-object-rest-spread/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["transform-destructuring", "proposal-object-rest-spread"] +} diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/number-key-with-object-rest-spread/exec.js b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/number-key-with-object-rest-spread/exec.js new file mode 100644 index 0000000000..fe160adb01 --- /dev/null +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/number-key-with-object-rest-spread/exec.js @@ -0,0 +1,10 @@ +const foo = { + 1: "a", + 2: "b", + 3: "c", +}; + +const { [1]: bar, ...rest } = foo; + +expect(bar).toBe("a"); +expect(rest).toEqual({ 2: "b", 3: "c" }); diff --git a/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/number-key-with-object-rest-spread/options.json b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/number-key-with-object-rest-spread/options.json new file mode 100644 index 0000000000..9fd3882905 --- /dev/null +++ b/packages/babel-plugin-transform-destructuring/test/fixtures/destructuring/number-key-with-object-rest-spread/options.json @@ -0,0 +1,3 @@ +{ + "plugins": ["transform-destructuring", "proposal-object-rest-spread"] +}