diff --git a/src/rules/prefer-array-from-map.test.ts b/src/rules/prefer-array-from-map.test.ts index 825cab5..8164e6e 100644 --- a/src/rules/prefer-array-from-map.test.ts +++ b/src/rules/prefer-array-from-map.test.ts @@ -33,7 +33,14 @@ ruleTester.run('prefer-array-from-map', preferArrayFromMap, { 'const result = [arr].map(x => x * 2)', // Empty array - 'const result = [].map(x => x * 2)' + 'const result = [].map(x => x * 2)', + + // Mapper can access the third `array` argument, which Array.from's + // mapper is never given + 'const result = [...arr].map((x, i, all) => all[i - 1])', + 'const result = [...arr].map(function(x, i, all) { return all[i - 1] })', + 'const result = [...arr].map((...args) => args[2])', + 'const result = [...arr].map((x, ...rest) => rest[1])' ], invalid: [ diff --git a/src/rules/prefer-array-from-map.ts b/src/rules/prefer-array-from-map.ts index c556d21..375a30c 100644 --- a/src/rules/prefer-array-from-map.ts +++ b/src/rules/prefer-array-from-map.ts @@ -54,12 +54,29 @@ export const preferArrayFromMap: Rule.RuleModule = { return; } + const mapper = node.arguments[0]!; + + // Array.from's mapper is called with (element, index) only, so a + // callback which can access the third `array` argument can't be + // converted + if ( + mapper.type === 'FunctionExpression' || + mapper.type === 'ArrowFunctionExpression' + ) { + if ( + mapper.params.length > 2 || + mapper.params.some((param) => param.type === 'RestElement') + ) { + return; + } + } + const spreadElement = arrayExpr.elements[0]; const iterableText = formatArguments( [spreadElement.argument], sourceCode ); - const mapperText = formatArguments([node.arguments[0]!], sourceCode); + const mapperText = formatArguments([mapper], sourceCode); context.report({ node,