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 rule no static typos #1209
Add rule no static typos #1209
Conversation
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.
Thanks, this looks great!
docs/rules/no-static-typos.md
Outdated
@@ -0,0 +1,59 @@ | |||
# Prevent casing typos when declaring static propTypes, contextType and defaultProps |
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.
Please add (react/no-static-typos)
on this line.
docs/rules/no-static-typos.md
Outdated
|
||
Ensure no casing typos were made declaring static class properties | ||
|
||
**Fixable:** This rule is automatically fixable using the `--fix` flag on the command line. |
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 shouldn't be fixable - it's not safe to do so.
It's a great rule to prevent people doing this by accident - but autofixing these can cause actual behavior changes in production. eslint core's policy is to never allow autofixes that could break 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.
Ok, I will remove it.
I was actually not aware of this policy. So only stylistic issues should be fixable? Adding removing lines, spaces, semi-colons?
FWIW, The actual help for --fix
actually says the following: This option instructs ESLint to try to fix as many issues as possible.
Considering the words "as many issues as possible" - I thought that every rule which we know how to fix should be auto fixable.
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.
It's not that it has to just be stylistic - but generally eslint errs on the side of caution to avoid breaking code.
If this rule warns, it'll only be for two reasons: 1) a typo, which is totally autofixable - and 2) a badly but intentionally chosen name, and the user needs to know to manually rename it.
docs/rules/no-static-typos.md
Outdated
|
||
* propTypes | ||
* contextTypes | ||
* defaultProps |
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 about childContextTypes
?
Tackled your comments. I was not aware of Also I wanted to ask: as I was working on this, I thought that it might be worth it to detect small spelling mistakes as well. We should be able to easily detect 1-letter spelling mistakes. But I am not sure how far this plugin wants to go? |
Detecting spelling mistakes seems like a slippery slope. |
9ad59da
to
3aa552c
Compare
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.
For each test case (that are currently all using babel-eslint
), can you please add a duplicate test case that uses the default parser?
The default parser throws an error. I assume that is the case because the class properties proposal is still stage-0 and it is not supported by espree (which is the default parser). This is the error that the test then gives: https://astexplorer.net/#/gist/da19b693a7a3d48bcc3fb249180b5295/a5875bd2c21133f64ce9f397ff82adb5e37da26a Please correct me if I am wrong, would need guidance what exactly needs to be changed. :) Edit: Did you mean that the following should also be validated? Because currently this is not checked and does not throw a warning. class Hello extends Component [}
Hello.pRopTyPeS = { ... } // should throw an error because of casing issues? I did remove the |
Indeed, I'm talking about assigning it outside the |
I added tests and support for assignment outside the class. But I cannot get it to work when assigning on a stateless function component: I am not sure how to detect whether the function is a stateless function component or just some random function yet. function MyComponent(props) {
return <div>{props.name}</div>;
}
QuestionList.PrOpTyPeS = {
name: PropTypes.string.isRequired,
}; |
We have |
I spent quite a bit of time on this but no luck so far. I cannot figure out how to properly detect a stateless function component so that the following becomes invalid: function MyComponent() { return (<div>{this.props.myprop}</div>) };
MyComponent.pRoPTyPeS = { myProp: PropTypes.string } But the following is valid (since it is not a stateless component): function SomeRandomFunction() { return {} };
MyComponent.pRoPTyPeS = { } I tried using I added all the test cases, maybe someone else has any idea? |
|
a487c4f
to
3804f34
Compare
So I finally managed to fix this. I also rebased everything unto the latest master. I ended up extending This way, I could now use I tried various other approaches from the existing |
README.md
Outdated
@@ -100,6 +100,7 @@ Finally, enable all of the rules that you would like to use. Use [our preset](# | |||
* [react/no-redundant-should-component-update](docs/rules/no-redundant-should-component-update.md): Prevent usage of `shouldComponentUpdate` when extending React.PureComponent | |||
* [react/no-render-return-value](docs/rules/no-render-return-value.md): Prevent usage of the return value of `React.render` | |||
* [react/no-set-state](docs/rules/no-set-state.md): Prevent usage of `setState` | |||
* [react/no-static-typos](docs/rules/no-static-typos.md): Prevent casing typos when declaring static class properties. |
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 addition to casing, it would be nice to flag also anything with a small levenshtein distance. That could be done as a separate PR.
And, if you are interested, it would be really cool to have a similar rule for detecting typos in lifecycle methods: #843
I wonder if this rule should have a more general name like react/no-typos
and make it work also for lifecycle methods?
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 suggested the spelling error detection also earlier in the PR: #1209 (comment) and reply: #1209 (comment)
I will look into the similar issue regarding lifecycle methods. Would be useful to have it there as well, as I never remember if it was prevProps
, nextProps
, prevState
or nextState
(which one and in which order).
I think the rename would make sense, if we add support for lifecycle methods... which I think, should be straight forward. (though I though that initially about this rule as well and it turned out to take a bit of time :D)
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.
as I never remember if it was prevProps, nextProps, prevState or nextState
To be clear, my suggestion is to apply this rule to lifecycle method names, not their arguments. e.g. componentWillMount
. A rule that enforces naming of lifecycle method arguments would be interesting, but I think that is definitely a different rule than typo detection.
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.
Even if we're planning on extending it in the future but not yet, then we should rename the rule to be more generic.
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.
Agreed. I will rename to no-typos
and update the docs accordingly.
We can then add casing typos for lifecycle methods in another PR. And we can look into detecting small Levenshtein distances in a separate PR as well.
Sounds good?
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.
Sounds great!
lib/rules/no-static-typos.js
Outdated
if (CLASS_PROP.toLowerCase() === propertyName.toLowerCase() && CLASS_PROP !== propertyName) { | ||
context.report({ | ||
node: node, | ||
message: 'Typo in static class property declaration' |
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.
It seems like this might be pretty straightforward to write a fixer for. Would you be interested in adding that?
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 a fixer is safe here; there's no way to know if it's intentional or not.
Fix an error with closing the code tag Add "fixable" to the documentation Add link to the main README
Added the rule name Decided to not mention all the possible properties that we check for in the title, as adding childContextTypes in the next commit may end up making this title too long.
findReturnStatement expect "node.value.body.body" to exist, but for FunctionDeclarations the correct path to the ReturnStatement is "node.body.body"
27fc5bc
to
84bd235
Compare
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.
We should also add tests for computed static property names (to ensure they're not reported).
Could you please elaborate a bit more what you mean exactly? I added a test case for this, as this was currently causing a crash:
And yeah - this is not supported. E.g. |
I expect, from the implementation, that computed property names are ignored. I'm asking for tests to ensure they are ignored - to prevent them accidentally being considered in the future, and to ensure that considering them is a breaking change. |
I understood why we want the test cases. I just wasn't 100% sure that I understood correctly what you meant with "computed static property names". I understood this was used for: const myObj = {
["myKey-" + getIndex()]: "myValue"
} But I don't see how this syntax can be used to declare these properties. The tests I added are basically what this would transpile to: const myObj = {}
myObj["myKey-" + getIndex()]: "myValue I hope that's all that is needed to finalize this, as I'd like to start focussing on the next steps. :) |
My attempt to add this rule. It seemed pretty basic... so here it is! I am open to new ideas and improvements to the rule. Please let me know!
Issue: #1189
Currently it only checks for
static
class properties. And only fordefaultProps
,contextTypes
andpropTypes
. It should be trivial to add new properties as well though.Because it only checks for static properties, it means that having
PropTypes
as a non-static class property or a method definition is still allowed. Although honestly I do not know why anyone would do that? Perhaps the rule can be extended to also warn in casepropTypes
is not declared as astatic
class property?The rule only works for React Components. Within classes that are not React components, anything is still possible.