Skip to content

Commit

Permalink
[Fix] no-array-index-key: catch .toString and String() usage
Browse files Browse the repository at this point in the history
Fixes #2813.
  • Loading branch information
RedTn authored and ljharb committed Sep 28, 2020
1 parent 1b307d3 commit 492b5f1
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -22,6 +22,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
* [`jsx-indent`]: Fix indent handling for closing parentheses ([#620][] @stefanbuck])
* [`prop-types`/`propTypes`]: follow a returned identifier to see if it is JSX ([#1046][] @ljharb)
* [`no-unused-state`]: TS: support `getDerivedStateFromProps` as an arrow function ([#2061][] @ljharb)
* [`no-array-index-key`]: catch `.toString` and `String()` usage ([#2813][] @RedTn)

### Changed
* [readme] change [`jsx-runtime`] link from branch to sha ([#3160][] @tatsushitoji)
Expand Down Expand Up @@ -51,6 +52,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
[#3160]: https://github.com/yannickcr/eslint-plugin-react/pull/3160
[#3133]: https://github.com/yannickcr/eslint-plugin-react/pull/3133
[#2921]: https://github.com/yannickcr/eslint-plugin-react/pull/2921
[#2813]: https://github.com/yannickcr/eslint-plugin-react/pull/2813
[#2753]: https://github.com/yannickcr/eslint-plugin-react/pull/2753
[#2061]: https://github.com/yannickcr/eslint-plugin-react/issues/2061
[#1817]: https://github.com/yannickcr/eslint-plugin-react/issues/1817
Expand Down
32 changes: 32 additions & 0 deletions lib/rules/no-array-index-key.js
Expand Up @@ -159,6 +159,38 @@ module.exports = {
node,
});
});

return;
}

if (node.type === 'CallExpression'
&& node.callee
&& node.callee.type === 'MemberExpression'
&& node.callee.object
&& isArrayIndex(node.callee.object)
&& node.callee.property
&& node.callee.property.type === 'Identifier'
&& node.callee.property.name === 'toString'
) {
// key={bar.toString()}
report(context, messages.noArrayIndex, 'noArrayIndex', {
node,
});
return;
}

if (node.type === 'CallExpression'
&& node.callee
&& node.callee.type === 'Identifier'
&& node.callee.name === 'String'
&& Array.isArray(node.arguments)
&& node.arguments.length > 0
&& isArrayIndex(node.arguments[0])
) {
// key={String(bar)}
report(context, messages.noArrayIndex, 'noArrayIndex', {
node: node.arguments[0],
});
}
}

Expand Down
39 changes: 39 additions & 0 deletions tests/lib/rules/no-array-index-key.js
Expand Up @@ -69,6 +69,21 @@ ruleTester.run('no-array-index-key', rule, {
{
code: 'foo.reduce((a, b) => a.concat(<Foo key={b.id} />), [])',
},
{
code: 'foo.map((bar, i) => <Foo key={i.baz.toString()} />)',
},
{
code: 'foo.map((bar, i) => <Foo key={i.toString} />)',
},
{
code: 'foo.map((bar, i) => <Foo key={String()} />)',
},
{
code: 'foo.map((bar, i) => <Foo key={String(baz)} />)',
},
{
code: 'foo.reduce((a, b) => a.concat(<Foo key={b.id} />), [])',
},
{
code: 'foo.reduce((a, b, i) => a.concat(<Foo key={b.id} />), [])',
},
Expand Down Expand Up @@ -251,6 +266,30 @@ ruleTester.run('no-array-index-key', rule, {
parserOptions: {
ecmaVersion: 2020,
},
},
{
code: `
foo.map((bar, index) => (
<Element key={index.toString()} bar={bar} />
))
`,
errors: [{ messageId: 'noArrayIndex' }],
},
{
code: `
foo.map((bar, index) => (
<Element key={String(index)} bar={bar} />
))
`,
errors: [{ messageId: 'noArrayIndex' }],
},
{
code: `
foo.map((bar, index) => (
<Element key={index} bar={bar} />
))
`,
errors: [{ messageId: 'noArrayIndex' }],
}
)),
});

0 comments on commit 492b5f1

Please sign in to comment.