Skip to content

Commit 492b5f1

Browse files
RedTnljharb
authored andcommitted
[Fix] no-array-index-key: catch .toString and String() usage
Fixes #2813.
1 parent 1b307d3 commit 492b5f1

File tree

3 files changed

+73
-0
lines changed

3 files changed

+73
-0
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
2222
* [`jsx-indent`]: Fix indent handling for closing parentheses ([#620][] @stefanbuck])
2323
* [`prop-types`/`propTypes`]: follow a returned identifier to see if it is JSX ([#1046][] @ljharb)
2424
* [`no-unused-state`]: TS: support `getDerivedStateFromProps` as an arrow function ([#2061][] @ljharb)
25+
* [`no-array-index-key`]: catch `.toString` and `String()` usage ([#2813][] @RedTn)
2526

2627
### Changed
2728
* [readme] change [`jsx-runtime`] link from branch to sha ([#3160][] @tatsushitoji)
@@ -51,6 +52,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
5152
[#3160]: https://github.com/yannickcr/eslint-plugin-react/pull/3160
5253
[#3133]: https://github.com/yannickcr/eslint-plugin-react/pull/3133
5354
[#2921]: https://github.com/yannickcr/eslint-plugin-react/pull/2921
55+
[#2813]: https://github.com/yannickcr/eslint-plugin-react/pull/2813
5456
[#2753]: https://github.com/yannickcr/eslint-plugin-react/pull/2753
5557
[#2061]: https://github.com/yannickcr/eslint-plugin-react/issues/2061
5658
[#1817]: https://github.com/yannickcr/eslint-plugin-react/issues/1817

lib/rules/no-array-index-key.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,38 @@ module.exports = {
159159
node,
160160
});
161161
});
162+
163+
return;
164+
}
165+
166+
if (node.type === 'CallExpression'
167+
&& node.callee
168+
&& node.callee.type === 'MemberExpression'
169+
&& node.callee.object
170+
&& isArrayIndex(node.callee.object)
171+
&& node.callee.property
172+
&& node.callee.property.type === 'Identifier'
173+
&& node.callee.property.name === 'toString'
174+
) {
175+
// key={bar.toString()}
176+
report(context, messages.noArrayIndex, 'noArrayIndex', {
177+
node,
178+
});
179+
return;
180+
}
181+
182+
if (node.type === 'CallExpression'
183+
&& node.callee
184+
&& node.callee.type === 'Identifier'
185+
&& node.callee.name === 'String'
186+
&& Array.isArray(node.arguments)
187+
&& node.arguments.length > 0
188+
&& isArrayIndex(node.arguments[0])
189+
) {
190+
// key={String(bar)}
191+
report(context, messages.noArrayIndex, 'noArrayIndex', {
192+
node: node.arguments[0],
193+
});
162194
}
163195
}
164196

tests/lib/rules/no-array-index-key.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,21 @@ ruleTester.run('no-array-index-key', rule, {
6969
{
7070
code: 'foo.reduce((a, b) => a.concat(<Foo key={b.id} />), [])',
7171
},
72+
{
73+
code: 'foo.map((bar, i) => <Foo key={i.baz.toString()} />)',
74+
},
75+
{
76+
code: 'foo.map((bar, i) => <Foo key={i.toString} />)',
77+
},
78+
{
79+
code: 'foo.map((bar, i) => <Foo key={String()} />)',
80+
},
81+
{
82+
code: 'foo.map((bar, i) => <Foo key={String(baz)} />)',
83+
},
84+
{
85+
code: 'foo.reduce((a, b) => a.concat(<Foo key={b.id} />), [])',
86+
},
7287
{
7388
code: 'foo.reduce((a, b, i) => a.concat(<Foo key={b.id} />), [])',
7489
},
@@ -251,6 +266,30 @@ ruleTester.run('no-array-index-key', rule, {
251266
parserOptions: {
252267
ecmaVersion: 2020,
253268
},
269+
},
270+
{
271+
code: `
272+
foo.map((bar, index) => (
273+
<Element key={index.toString()} bar={bar} />
274+
))
275+
`,
276+
errors: [{ messageId: 'noArrayIndex' }],
277+
},
278+
{
279+
code: `
280+
foo.map((bar, index) => (
281+
<Element key={String(index)} bar={bar} />
282+
))
283+
`,
284+
errors: [{ messageId: 'noArrayIndex' }],
285+
},
286+
{
287+
code: `
288+
foo.map((bar, index) => (
289+
<Element key={index} bar={bar} />
290+
))
291+
`,
292+
errors: [{ messageId: 'noArrayIndex' }],
254293
}
255294
)),
256295
});

0 commit comments

Comments
 (0)