diff --git a/CHANGELOG.md b/CHANGELOG.md index 5dd37b8e99..877ddd2eba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,8 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel * [`prop-types`]: Detect TypeScript types for destructured default prop values ([#2780][] @sunghyunjo) * [`jsx-pascal-case`]: Handle single character namespaced component ([#2791][] @daviferreira) * [`jsx-closing-bracket-location`]: In `tag-aligned`, made a distinction between tabs and spaces ([#2796][] @Moong0122) -* [`jsx-handler-names`]: false positive when handler name begins with number ([#2801][] @mikol) +* [`jsx-handler-names`]: false positive when handler name begins with number ([#1689][] @jsphstls) +* [`prop-types`]: Detect JSX returned by sequential expression ([#2801][] @mikol) [#2801]: https://github.com/yannickcr/eslint-plugin-react/pull/2801 [#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 [#2767]: https://github.com/yannickcr/eslint-plugin-react/pull/2767 [#2761]: https://github.com/yannickcr/eslint-plugin-react/pull/2761 [#2748]: https://github.com/yannickcr/eslint-plugin-react/pull/2748 +[#1689]: https://github.com/yannickcr/eslint-plugin-react/pull/1689 ## [7.20.6] - 2020.08.12 diff --git a/lib/util/Components.js b/lib/util/Components.js index 71e400be77..fe90ccf05e 100644 --- a/lib/util/Components.js +++ b/lib/util/Components.js @@ -71,6 +71,12 @@ function isReturnsLogicalJSX(node, property, strict) { : (returnsLogicalJSXLeft || returnsLogicalJSXRight); } +function isReturnsSequentialJSX(node, property) { + return node[property] + && node[property].type === 'SequenceExpression' + && jsxUtil.isJSX(node[property].expressions[node[property].expressions.length - 1]); +} + const Lists = new WeakMap(); /** @@ -457,6 +463,7 @@ function componentRule(rule, context) { const returnsConditionalJSX = isReturnsConditionalJSX(node, property, strict); const returnsLogicalJSX = isReturnsLogicalJSX(node, property, strict); + const returnsSequentialJSX = isReturnsSequentialJSX(node, property); const returnsJSX = node[property] && jsxUtil.isJSX(node[property]); const returnsPragmaCreateElement = this.isCreateElement(node[property]); @@ -464,6 +471,7 @@ function componentRule(rule, context) { return !!( returnsConditionalJSX || returnsLogicalJSX + || returnsSequentialJSX || returnsJSX || returnsPragmaCreateElement ); diff --git a/tests/lib/rules/prop-types.js b/tests/lib/rules/prop-types.js index 29b04794cd..ab40f13bd3 100644 --- a/tests/lib/rules/prop-types.js +++ b/tests/lib/rules/prop-types.js @@ -2501,6 +2501,20 @@ ruleTester.run('prop-types', rule, { export default function() {} ` }, + { + code: ` + function Component(props) { + return 0, +
+ Hello, { props.name }! +
+ } + + Component.propTypes = { + name: PropTypes.string.isRequired + } + ` + }, parsers.TS([ { code: ` @@ -5591,6 +5605,19 @@ ruleTester.run('prop-types', rule, { message: '\'foo.baz\' is missing in props validation' }] }, + { + code: ` + function Component(props) { + return 0, +
+ Hello, { props.name }! +
+ } + `, + errors: [{ + message: '\'name\' is missing in props validation' + }] + }, parsers.TS([ { code: `