Skip to content

Commit f02e8ae

Browse files
toshi-tomaljharb
authored andcommitted
[Fix] prop-types: Does not validate missing propTypes for LogicalExpression
1 parent 8df4943 commit f02e8ae

File tree

2 files changed

+57
-12
lines changed

2 files changed

+57
-12
lines changed

lib/util/Components.js

+29-12
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,30 @@ function mergeUsedPropTypes(propsList, newPropsList) {
4646
return propsList.concat(propsToAdd);
4747
}
4848

49+
function isReturnsConditionalJSX(node, property, strict) {
50+
const returnsConditionalJSXConsequent = node[property] &&
51+
node[property].type === 'ConditionalExpression' &&
52+
jsxUtil.isJSX(node[property].consequent);
53+
const returnsConditionalJSXAlternate = node[property] &&
54+
node[property].type === 'ConditionalExpression' &&
55+
jsxUtil.isJSX(node[property].alternate);
56+
return strict ?
57+
(returnsConditionalJSXConsequent && returnsConditionalJSXAlternate) :
58+
(returnsConditionalJSXConsequent || returnsConditionalJSXAlternate);
59+
}
60+
61+
function isReturnsLogicalJSX(node, property, strict) {
62+
const returnsLogicalJSXLeft = node[property] &&
63+
node[property].type === 'LogicalExpression' &&
64+
jsxUtil.isJSX(node[property].left);
65+
const returnsLogicalJSXRight = node[property] &&
66+
node[property].type === 'LogicalExpression' &&
67+
jsxUtil.isJSX(node[property].right);
68+
return strict ?
69+
(returnsLogicalJSXLeft && returnsLogicalJSXRight) :
70+
(returnsLogicalJSXLeft || returnsLogicalJSXRight);
71+
}
72+
4973
const Lists = new WeakMap();
5074

5175
/**
@@ -373,22 +397,15 @@ function componentRule(rule, context) {
373397
return false;
374398
}
375399

376-
const returnsConditionalJSXConsequent = node[property] &&
377-
node[property].type === 'ConditionalExpression' &&
378-
jsxUtil.isJSX(node[property].consequent);
379-
const returnsConditionalJSXAlternate = node[property] &&
380-
node[property].type === 'ConditionalExpression' &&
381-
jsxUtil.isJSX(node[property].alternate);
382-
const returnsConditionalJSX = strict ?
383-
(returnsConditionalJSXConsequent && returnsConditionalJSXAlternate) :
384-
(returnsConditionalJSXConsequent || returnsConditionalJSXAlternate);
400+
const returnsConditionalJSX = isReturnsConditionalJSX(node, property, strict);
401+
const returnsLogicalJSX = isReturnsLogicalJSX(node, property, strict);
385402

386-
const returnsJSX = node[property] &&
387-
jsxUtil.isJSX(node[property]);
403+
const returnsJSX = node[property] && jsxUtil.isJSX(node[property]);
388404
const returnsPragmaCreateElement = this.isCreateElement(node[property]);
389405

390-
return Boolean(
406+
return !!(
391407
returnsConditionalJSX ||
408+
returnsLogicalJSX ||
392409
returnsJSX ||
393410
returnsPragmaCreateElement
394411
);

tests/lib/rules/prop-types.js

+28
Original file line numberDiff line numberDiff line change
@@ -2465,6 +2465,19 @@ ruleTester.run('prop-types', rule, {
24652465
pragma: 'Foo'
24662466
}
24672467
}
2468+
},
2469+
{
2470+
code: `
2471+
const Foo = ({length, ordering}) => (
2472+
length > 0 && (
2473+
<Paginator items={ordering} pageSize={10} />
2474+
)
2475+
);
2476+
Foo.propTypes = {
2477+
length: PropTypes.number,
2478+
ordering: PropTypes.array
2479+
};
2480+
`
24682481
}
24692482
],
24702483

@@ -4895,6 +4908,21 @@ ruleTester.run('prop-types', rule, {
48954908
errors: [{
48964909
message: '\'foo.baz\' is missing in props validation'
48974910
}]
4911+
},
4912+
{
4913+
code: `
4914+
const Foo = ({length, ordering}) => (
4915+
length > 0 && (
4916+
<Paginator items={ordering} pageSize={10} />
4917+
)
4918+
);
4919+
`,
4920+
errors: [{
4921+
message: '\'length\' is missing in props validation'
4922+
},
4923+
{
4924+
message: '\'ordering\' is missing in props validation'
4925+
}]
48984926
}
48994927
]
49004928
});

0 commit comments

Comments
 (0)