Skip to content

Commit 74c4eed

Browse files
mikolljharb
authored andcommitted
[Fix] prop-types: Detect JSX returned by sequential expression
Resolves #2800. Implements `isReturnsSequentialJSX()` and uses it in `isReturningJSX()` (in conjunction with `isReturnsConditionalJSX()` and `isReturnsLogicalJSX()`).
1 parent 2bf24b2 commit 74c4eed

File tree

3 files changed

+38
-1
lines changed

3 files changed

+38
-1
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel
1818
* [`prop-types`]: Detect TypeScript types for destructured default prop values ([#2780][] @sunghyunjo)
1919
* [`jsx-pascal-case`]: Handle single character namespaced component ([#2791][] @daviferreira)
2020
* [`jsx-closing-bracket-location`]: In `tag-aligned`, made a distinction between tabs and spaces ([#2796][] @Moong0122)
21-
* [`jsx-handler-names`]: false positive when handler name begins with number ([#2801][] @mikol)
21+
* [`jsx-handler-names`]: false positive when handler name begins with number ([#1689][] @jsphstls)
22+
* [`prop-types`]: Detect JSX returned by sequential expression ([#2801][] @mikol)
2223

2324
[#2801]: https://github.com/yannickcr/eslint-plugin-react/pull/2801
2425
[#2796]: https://github.com/yannickcr/eslint-plugin-react/pull/2796
@@ -33,6 +34,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel
3334
[#2767]: https://github.com/yannickcr/eslint-plugin-react/pull/2767
3435
[#2761]: https://github.com/yannickcr/eslint-plugin-react/pull/2761
3536
[#2748]: https://github.com/yannickcr/eslint-plugin-react/pull/2748
37+
[#1689]: https://github.com/yannickcr/eslint-plugin-react/pull/1689
3638

3739
## [7.20.6] - 2020.08.12
3840

lib/util/Components.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ function isReturnsLogicalJSX(node, property, strict) {
7171
: (returnsLogicalJSXLeft || returnsLogicalJSXRight);
7272
}
7373

74+
function isReturnsSequentialJSX(node, property) {
75+
return node[property]
76+
&& node[property].type === 'SequenceExpression'
77+
&& jsxUtil.isJSX(node[property].expressions[node[property].expressions.length - 1]);
78+
}
79+
7480
const Lists = new WeakMap();
7581

7682
/**
@@ -457,13 +463,15 @@ function componentRule(rule, context) {
457463

458464
const returnsConditionalJSX = isReturnsConditionalJSX(node, property, strict);
459465
const returnsLogicalJSX = isReturnsLogicalJSX(node, property, strict);
466+
const returnsSequentialJSX = isReturnsSequentialJSX(node, property);
460467

461468
const returnsJSX = node[property] && jsxUtil.isJSX(node[property]);
462469
const returnsPragmaCreateElement = this.isCreateElement(node[property]);
463470

464471
return !!(
465472
returnsConditionalJSX
466473
|| returnsLogicalJSX
474+
|| returnsSequentialJSX
467475
|| returnsJSX
468476
|| returnsPragmaCreateElement
469477
);

tests/lib/rules/prop-types.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2501,6 +2501,20 @@ ruleTester.run('prop-types', rule, {
25012501
export default function() {}
25022502
`
25032503
},
2504+
{
2505+
code: `
2506+
function Component(props) {
2507+
return 0,
2508+
<div>
2509+
Hello, { props.name }!
2510+
</div>
2511+
}
2512+
2513+
Component.propTypes = {
2514+
name: PropTypes.string.isRequired
2515+
}
2516+
`
2517+
},
25042518
parsers.TS([
25052519
{
25062520
code: `
@@ -5591,6 +5605,19 @@ ruleTester.run('prop-types', rule, {
55915605
message: '\'foo.baz\' is missing in props validation'
55925606
}]
55935607
},
5608+
{
5609+
code: `
5610+
function Component(props) {
5611+
return 0,
5612+
<div>
5613+
Hello, { props.name }!
5614+
</div>
5615+
}
5616+
`,
5617+
errors: [{
5618+
message: '\'name\' is missing in props validation'
5619+
}]
5620+
},
55945621
parsers.TS([
55955622
{
55965623
code: `

0 commit comments

Comments
 (0)