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
[Fix] prop-types
: Support typescript props interface extension and TSTypeAliasDeclaration
#2721
Conversation
…ypescript props interface extension and TSTypeAliasDeclaration Fixes jsx-eslint#2654. Fixes jsx-eslint#2719. Fixes jsx-eslint#2703. Co-authored-by: Hank Chen <hank121314@gmail.com> Co-authored-by: Jordan Harband <ljharb@gmail.com>
prop-types
: Support typescript props interface extension and TSTypeAliasDeclarationprop-types
: Support typescript props interface extension and TSTypeAliasDeclaration
prop-types
: Support typescript props interface extension and TSTypeAliasDeclarationprop-types
: Support typescript props interface extension and TSTypeAliasDeclaration
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 seems great
lib/util/propTypes.js
Outdated
*/ | ||
function isFunctionType(node) { | ||
if (node.type) { | ||
const regexp = new RegExp('^(?:Function(?:Declaration|Expression)|ArrowFunctionExpression)$'); |
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.
const regexp = new RegExp('^(?:Function(?:Declaration|Expression)|ArrowFunctionExpression)$'); | |
const regexp = /^(?:Function(?:Declaration|Expression)|ArrowFunctionExpression)$/; |
new RegExp
should never be used when a literal suffices.
altho this seems like it'd be clearer as a chain of if
s rather than using a regex.
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 for your advice!
How about using Array.includes ?
function isFunctionType(node) {
if (node.type) {
return ['FunctionDeclaration', 'FunctionExpression', 'ArrowFunctionExpression'].includes(node.type);
}
return false;
}
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.
That also seems like needless runtime overhead for only three choices. I'd prefer a simple if chain.
Hi @ljharb ! |
@hank121314 in general it's best if we use both - ie, duplicate the test cases - so we can be sure that things stay working as much as possible on the old TS parser. |
@@ -3226,7 +3226,7 @@ ruleTester.run('no-unused-prop-types', rule, { | |||
bar, | |||
}; | |||
`, | |||
parser: parsers.TYPESCRIPT_ESLINT | |||
parser: parsers['@TYPESCRIPT_ESLINT'] |
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.
specifically, all these test cases with the old TS parser should be left untouched, and duplicated, with the duplicate using the new TS parser.
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 have added it back.
But I think we might need to deprecated old TS parser someday.
The ast tree between two parser have a big difference.
It is really hard to support both parser for their own ast tree.
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!
4f27dae
to
ac422ad
Compare
I've rebased the branch for you; the eslint 4 + node 4 tests are failing, but I suspect that's because the new TS parser doesn't work there. I'll finish updating the branch to handle that tomorrow, and then land it. |
Yes, seems that new TS parser only support eslint version greater than 5. |
@hank121314 ok, i think i've addressed that problem, but I'm now seeing a few tests failing locally - one example: type User = {
user: string;
}
type Props = User & {
};
export default (props: Props) => {
const { userId, user } = props;
if (userId === 0) {
return <p>userId is 0</p>;
}
return null;
}; is warning on both (Please delete your local branch and check it out fresh, so you can work on top of my rebase) |
I'm sorry to say this pr doesn't support old TS parser for any of intersectionType or extension. |
@hank121314 ah - so, one option is certainly to comment out the "old TS parser" tests, land this, and fix them later - but i'd prefer to do them all at once, if you're willing :-) |
It's my pleasure! I have pushed the latest version with old TS parser support and add some test case in no-unused-prop-types. |
k, figured out the test failures in eslint 4 :-) rebased again. |
Hi. It not working if extented interface exist in another file. |
@sergeu90 cross-file linting isn't practical. |
@ljharb If I have interface product for example and I want validate props in component product. I need move interface to the file product component right? But if I have multiply places where I want use product then I have global product interface and local product interface in the product component? And if I want to add new property I need add to 2 places? |
Yes, that's just a limitation in linting. It's more clear though to repeat prop names so that someone doesn't have to go read another file to find out what props a component takes. |
@ljharb Thanks for reply |
Fixes #2654. Fixes #2719. Fixes #2703.
Now support the following typescript syntax for prop validation,
but extension only support with parser @typescript-eslint/parser since typescript-eslint-parser is deprecated.
ReturnType can only accept one parameter, and the parameter should be function type, and that function should return an ObjectExpression.
Thanks you so much for your code review!