From 56f78882c6d20bdd0a0ee3ee14d26d71dadd330c Mon Sep 17 00:00:00 2001 From: James Garbutt <43081j@users.noreply.github.com> Date: Thu, 17 Sep 2026 14:14:07 +0100 Subject: [PATCH] fix(prefer-array-from-map): don't flag mappers with >2 params If a mapper has more than 2 parameters, it can't be represented in `Array.from` since those mappers only receive two arguments. --- src/rules/prefer-array-from-map.test.ts | 9 ++++++++- src/rules/prefer-array-from-map.ts | 19 ++++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) 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,