diff --git a/packages/babel-plugin-transform-parameters/src/rest.js b/packages/babel-plugin-transform-parameters/src/rest.js index eccd548aec4c..cfba76ce4ae4 100644 --- a/packages/babel-plugin-transform-parameters/src/rest.js +++ b/packages/babel-plugin-transform-parameters/src/rest.js @@ -155,6 +155,16 @@ const memberExpressionOptimisationVisitor = { } }, }; + +function getParamsCount(node) { + let count = node.params.length; + // skip the first parameter if it is a TypeScript 'this parameter' + if (count > 0 && t.isIdentifier(node.params[0], { name: "this" })) { + count -= 1; + } + return count; +} + function hasRest(node) { const length = node.params.length; return length > 0 && t.isRestElement(node.params[length - 1]); @@ -244,10 +254,12 @@ export default function convertFunctionRest(path) { node.body.body.unshift(declar); } + const paramsCount = getParamsCount(node); + // check and optimise for extremely common cases const state = { references: [], - offset: node.params.length, + offset: paramsCount, argumentsNode: argsId, outerBinding: scope.getBindingIdentifier(rest.name), @@ -297,12 +309,12 @@ export default function convertFunctionRest(path) { state.candidates.map(({ path }) => path), ); - const start = t.numericLiteral(node.params.length); + const start = t.numericLiteral(paramsCount); const key = scope.generateUidIdentifier("key"); const len = scope.generateUidIdentifier("len"); let arrKey, arrLen; - if (node.params.length) { + if (paramsCount) { // this method has additional params, so we need to subtract // the index of the current argument position from the // position in the array that we want to populate diff --git a/packages/babel-plugin-transform-parameters/test/fixtures/parameters/options.json b/packages/babel-plugin-transform-parameters/test/fixtures/parameters/options.json index 4ee046b12d4c..4698618caab7 100644 --- a/packages/babel-plugin-transform-parameters/test/fixtures/parameters/options.json +++ b/packages/babel-plugin-transform-parameters/test/fixtures/parameters/options.json @@ -2,6 +2,7 @@ "plugins": [ "proposal-class-properties", "external-helpers", + "syntax-typescript", "syntax-flow", "transform-parameters", "transform-block-scoping", diff --git a/packages/babel-plugin-transform-parameters/test/fixtures/parameters/rest-ts-this-parameter/input.js b/packages/babel-plugin-transform-parameters/test/fixtures/parameters/rest-ts-this-parameter/input.js new file mode 100644 index 000000000000..1d2875453ecd --- /dev/null +++ b/packages/babel-plugin-transform-parameters/test/fixtures/parameters/rest-ts-this-parameter/input.js @@ -0,0 +1,7 @@ +function u(this: Foo, ...items) { + items[0]; +} + +function v(this: Foo, event: string, ...args: any[]) { + args; +} diff --git a/packages/babel-plugin-transform-parameters/test/fixtures/parameters/rest-ts-this-parameter/output.js b/packages/babel-plugin-transform-parameters/test/fixtures/parameters/rest-ts-this-parameter/output.js new file mode 100644 index 000000000000..55822308fd13 --- /dev/null +++ b/packages/babel-plugin-transform-parameters/test/fixtures/parameters/rest-ts-this-parameter/output.js @@ -0,0 +1,11 @@ +function u(this: Foo) { + arguments.length <= 0 ? undefined : arguments[0]; +} + +function v(this: Foo, event: string) { + for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + args; +}