Skip to content

Commit

Permalink
[Fix] prop-types: default argument does not count as props-types de…
Browse files Browse the repository at this point in the history
…claration

Fixes #2867.
  • Loading branch information
golopot authored and ljharb committed Dec 15, 2020
1 parent 23da1ee commit 9ec87e5
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 75 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -19,8 +19,10 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel
* [`no-typos`]: avoid crash with computed method name ([#2870][] @ljharb, @AriPerkkio)
* [`jsx-max-depth`]: avoid crash with childless jsx child ([#2869][] @ljharb, @AriPerkkio)
* [`no-unknown-property`]: avoid crash with prop named with Object.prototype key ([#2879][] @ljharb, @AriPerkkio)
* [`prop-types`]: default argument does not count as props-types declaration ([#2877][] @golopot)

[#2879]: https://github.com/yannickcr/eslint-plugin-react/issues/2879
[#2877]: https://github.com/yannickcr/eslint-plugin-react/pull/2877
[#2875]: https://github.com/yannickcr/eslint-plugin-react/issues/2875
[#2871]: https://github.com/yannickcr/eslint-plugin-react/issues/2871
[#2870]: https://github.com/yannickcr/eslint-plugin-react/issues/2870
Expand Down
34 changes: 0 additions & 34 deletions lib/rules/prop-types.js
Expand Up @@ -137,37 +137,6 @@ module.exports = {
return true;
}

/**
* Checks if the prop is declared in destructured params
* @param {Object[]} params List of destructured param among props without declaredPropTypes
* @returns {Boolean} True if the prop is declared, false if not.
*/
function isDeclaredInDestructuredParam(params) {
let result = true;
params.forEach((param) => {
if (!param.properties) {
result = false;
return;
}
param.properties.forEach((property) => {
if (property.type === 'RestElement' || property.type === 'ExperimentalRestProperty') {
return;
}
const type = property.value.type;
const right = property.value.right;
if (type !== 'AssignmentPattern') {
result = false;
return;
}
if (type === 'AssignmentPattern' && right && right.expression && right.expression.type && right.expression.type !== 'Literal') {
result = false;
}
});
});

return result;
}

/**
* Checks if the prop is declared
* @param {ASTNode} node The AST node being checked.
Expand All @@ -185,9 +154,6 @@ module.exports = {
return true;
}

if (component && !isDeclared && !component.declaredPropTypes && component.node.params && (component.node.type === 'FunctionDeclaration' || component.node.type === 'FunctionExpression' || component.node.type === 'ArrowFunctionExpression')) {
return isDeclaredInDestructuredParam(component.node.params);
}
node = node.parent;
}
return false;
Expand Down
98 changes: 57 additions & 41 deletions tests/lib/rules/prop-types.js
Expand Up @@ -2987,46 +2987,6 @@ ruleTester.run('prop-types', rule, {
`,
parser: parsers['@TYPESCRIPT_ESLINT']
},
{
code: `
function Foo({ foo = "" }): JSX.Element {
return <div>{foo}</div>;
}
`,
parser: parsers['@TYPESCRIPT_ESLINT']
},
{
code: `
function Foo({ bar = "" as string }): JSX.Element {
return <div>{bar}</div>;
}
`,
parser: parsers['@TYPESCRIPT_ESLINT']
},
{
code: `
export default function ({ value = 'World' }) {
return <h1>Hello {value}</h1>
}
`,
parser: parsers['@TYPESCRIPT_ESLINT']
},
{
code: `
const Foo: JSX.Element = ({ bar = "" }) => {
return <div>{bar}</div>;
}
`,
parser: parsers['@TYPESCRIPT_ESLINT']
},
{
code: `
const Foo: JSX.Element = function foo ({ bar = "" }) {
return <div>{bar}</div>;
}
`,
parser: parsers['@TYPESCRIPT_ESLINT']
},
// Issue: #2795
{
code: `
Expand Down Expand Up @@ -4364,7 +4324,19 @@ ruleTester.run('prop-types', rule, {
errors: [
{message: '\'name.constructor.firstname\' is missing in props validation'}
]
}, {
},
{
code: `
function Hello({ foo = '' }) {
return <p>{foo}</p>
}
`,
errors: [
{message: '\'foo\' is missing in props validation'}
],
parser: parsers.BABEL_ESLINT
},
{
code: [
'function SomeComponent({bar}) {',
' function f({foo}) {}',
Expand Down Expand Up @@ -6216,6 +6188,50 @@ ruleTester.run('prop-types', rule, {
errors: [{
message: "'type' is missing in props validation"
}]
},
{
code: `
const Foo: JSX.Element = ({ bar = "" }) => {
return <div>{bar}</div>;
}
`,
errors: [
{message: '\'bar\' is missing in props validation'}
],
parser: parsers['@TYPESCRIPT_ESLINT']
},
{
code: `
function Foo({ foo = "" }): JSX.Element {
return <div>{foo}</div>;
}
`,
errors: [
{message: '\'foo\' is missing in props validation'}
],
parser: parsers['@TYPESCRIPT_ESLINT']
},
{
code: `
const Foo: JSX.Element = function foo ({ bar = "" }) {
return <div>{bar}</div>;
}
`,
errors: [
{message: '\'bar\' is missing in props validation'}
],
parser: parsers['@TYPESCRIPT_ESLINT']
},
{
code: `
function Foo({ bar = "" as string }): JSX.Element {
return <div>{bar}</div>;
}
`,
errors: [
{message: '\'bar\' is missing in props validation'}
],
parser: parsers['@TYPESCRIPT_ESLINT']
}
])
)
Expand Down

0 comments on commit 9ec87e5

Please sign in to comment.