Skip to content

Commit 8e9e6c5

Browse files
hank121314ljharb
authored andcommitted
[Fix] prop-types: handle component returning null
Fixes jsx-eslint#2705.
1 parent ee4bad3 commit 8e9e6c5

File tree

2 files changed

+62
-23
lines changed

2 files changed

+62
-23
lines changed

lib/util/propTypes.js

+1-22
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ const variableUtil = require('./variable');
1212
const versionUtil = require('./version');
1313
const propWrapperUtil = require('./propWrapper');
1414
const getKeyValue = require('./ast').getKeyValue;
15-
const findReturnStatement = require('./ast').findReturnStatement;
16-
const isJSX = require('./jsx').isJSX;
1715

1816
/**
1917
* Checks if we are declaring a props as a generic type in a flow-annotated class.
@@ -72,25 +70,6 @@ function isInsideClassBody(node) {
7270
return false;
7371
}
7472

75-
/**
76-
* Checks if a node is a Function and return JSXElement
77-
*
78-
* @param {ASTNode} node the AST node being checked.
79-
* @returns {Boolean} True if the node is a Function and return JSXElement.
80-
*/
81-
function isJSXFunctionComponent(node) {
82-
if (node.type === 'ArrowFunctionExpression' || node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression') {
83-
const res = findReturnStatement(node);
84-
// If function return JSXElement with return keyword.
85-
if (res) {
86-
return isJSX(res.argument);
87-
}
88-
// If function return JSXElement without return keyword;
89-
return isJSX(node.body);
90-
}
91-
return false;
92-
}
93-
9473
module.exports = function propTypesInstructions(context, components, utils) {
9574
// Used to track the type annotations in scope.
9675
// Necessary because babel's scopes do not track type annotations.
@@ -699,7 +678,7 @@ module.exports = function propTypesInstructions(context, components, utils) {
699678
}
700679

701680
// Should ignore function that not return JSXElement
702-
if (!isJSXFunctionComponent(node)) {
681+
if (!utils.isReturningJSXOrNull(node)) {
703682
return;
704683
}
705684

tests/lib/rules/prop-types.js

100755100644
+61-1
Original file line numberDiff line numberDiff line change
@@ -2524,7 +2524,52 @@ ruleTester.run('prop-types', rule, {
25242524
MyComponent.propTypes = {
25252525
hello: PropTypes.string.isRequired,
25262526
};
2527-
`
2527+
`,
2528+
{
2529+
code: `
2530+
interface Props {
2531+
value?: string;
2532+
}
2533+
2534+
// without the | null, all ok, with it, it is broken
2535+
function Test ({ value }: Props): React.ReactElement<Props> | null {
2536+
if (!value) {
2537+
return null;
2538+
}
2539+
2540+
return <div>{value}</div>;
2541+
}`,
2542+
parser: parsers.TYPESCRIPT_ESLINT
2543+
},
2544+
{
2545+
code: `
2546+
interface Props {
2547+
value?: string;
2548+
}
2549+
2550+
// without the | null, all ok, with it, it is broken
2551+
function Test ({ value }: Props): React.ReactElement<Props> | null {
2552+
if (!value) {
2553+
return <div>{value}</div>;;
2554+
}
2555+
2556+
return null;
2557+
}`,
2558+
parser: parsers.TYPESCRIPT_ESLINT
2559+
},
2560+
{
2561+
code: `
2562+
interface Props {
2563+
value?: string;
2564+
}
2565+
const Hello = (props: Props) => {
2566+
if(props.value) {
2567+
return <div></div>;
2568+
}
2569+
return null;
2570+
}`,
2571+
parser: parsers.TYPESCRIPT_ESLINT
2572+
}
25282573
],
25292574

25302575
invalid: [
@@ -5101,6 +5146,21 @@ ruleTester.run('prop-types', rule, {
51015146
errors: [{
51025147
message: '\'foo.baz\' is missing in props validation'
51035148
}]
5149+
},
5150+
{
5151+
code: `
5152+
interface Props {
5153+
}
5154+
const Hello = (props: Props) => {
5155+
if(props.value) {
5156+
return <div></div>;
5157+
}
5158+
return null;
5159+
}`,
5160+
parser: parsers.TYPESCRIPT_ESLINT,
5161+
errors: [{
5162+
message: '\'value\' is missing in props validation'
5163+
}]
51045164
}
51055165
]
51065166
});

0 commit comments

Comments
 (0)