-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add new rule 'default-props-match-prop-types' #1087
Conversation
Thanks for the contribution! I haven't had time to review the code here yet, but I wanted to mention that I think I'm not quite sure what a good name might be. Maybe something along the lines of Also, I'm not entirely sure this makes sense as a separate rule instead of enhancing the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your test cases look very thorough!
/** | ||
* Checks if the Identifier node passed in looks like a defaultProps declaration. | ||
* @param {ASTNode} node The node to check. Must be an Identifier node. | ||
* @returns {Boolean} `true` if the node is a defaultProps declaration, `false` if not |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think any of these spaces are needed; do we typically visually align these comments in other rules?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Happy to make changes, but this code is nearly identical to require-default-props
. Do you want me to update the source there, too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in that case (that our rules already are inconsistent) then don't worry about it; it can be cleaned up in a separate PR.
* @returns {Boolean} `true` if the node is a defaultProps declaration, `false` if not | ||
*/ | ||
function isDefaultPropsDeclaration(node) { | ||
return (getPropertyName(node) === 'defaultProps' || getPropertyName(node) === 'getDefaultProps'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's cache the property name rather than calling the function twice.
|
||
// e.g.: | ||
// MyComponent.propTypes.baz = React.PropTypes.string; | ||
if (node.parent.type === 'MemberExpression' && node.parent.parent.type === 'AssignmentExpression') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will node.parent
always have a .parent
node?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's unlikely you wouldn't have a parent node in the case of a MemberExpression
whose parent is a MemberExpression
and belongs to a Component. But, I will admit I'm not intimately familiar with this code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know much of anything about AST nodes, I just want to avoid a crash in the future when a new node type comes out
return; | ||
} | ||
|
||
var isPropType = getPropertyName(node) === 'propTypes'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's cache the property name here rather than calling the function thrice.
Hmm, that makes sense that "invalid" isn't the best name. |
I do think it belongs as a separate rule since it warns on defaults, not prop types. |
|
A defaultProp for a required prop is arguably not "useless" since it may serve as documentation (not that I would ever use the option that allows it) so I don't think that's the right word.
Let's keep bikeshedding on the name, might as well pick the best one now. |
@lencioni A rule that validates the types of the |
I addressed some of the concerns raised in the review, but understand we're still searching for a good name. |
Anyone had any good ideas on the naming? Nothing particularly new has come to me. Maybe |
What about |
That seems more in keeping with @lencioni 's checker that would validate types. |
I think |
I'm curious how accurate we could be in matching the types. Certainly simple types would be easy, more complicated ones could easily become problematic. If you like the new name a lot, I can update the PR to the new name. |
I think matching the types will likely only be possible when using the built-in I think "match" doesn't necessarily connote "types match", which is why I don't think having the option to match types is a blocker. I mainly just want to get this in, and I think that's a good enough name ¯\_(ツ)_/¯ |
3118f4d
to
0b2c3e2
Compare
Updated the name of the rule and rebased on master. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great overall!
'use strict'; | ||
|
||
var has = require('has'); | ||
var find = require('array.prototype.find'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is no longer necessary, since master now only supports node 4+
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's sad is I originally implemented with Array.find()
but realized this didn't match with the (then) current style.
* @returns {ASTNode|null} Return null if the variable could not be found, ASTNode otherwise. | ||
*/ | ||
function findVariableByName(name) { | ||
var variable = find(variableUtil.variablesInScope(context), function(item) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so this can be const variable = variableUtil.variablesInScope(context).find(item => item.name === name);
* from this ObjectExpression can't be resolved. | ||
*/ | ||
function getDefaultPropsFromObjectExpression(objectExpression) { | ||
var hasSpread = find(objectExpression.properties, function(property) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and this
} | ||
|
||
function propFromName(propTypes, name) { | ||
return find(propTypes, function (prop) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and this can be return propTypes.find(prop => prop.name === name);
Enact-DCO-1.0-Signed-off-by: Roy Sutton [email protected]
Updated all the |
Anything else needed for this? |
Sorry for the delay. I'll give this another day or so, and if there's no objections, I'll merge it. |
Whoops, looks like I didn't add the rule to the README.md in the root. Should I create a separate PR for that? |
@webOS101 yes, thanks, that'd be great! |
Fixes #1022
There's currently one caveat that I haven't addressed: If there are no
propTypes
at all no warnings are issued. I didn't distinguish between that case and the case where they are not able to be determined (e.g.: external import). Also, this rule may conflict withrequire-default-props
as I am re-using the same component members, though testing did not reveal any problems using the two rules together.