Skip to content
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

[Refactor] extract type parameters to a variable #3634

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,14 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
* [`jsx-key`]: detect conditional returns ([#3630][] @yialo)
* [`jsx-newline`]: prevent a crash when `allowMultilines ([#3633][] @ljharb)

### Changed
* [Refactor] `propTypes`: extract type params to var ([#3634][] @HenryBrown0)
* [Refactor] [`boolean-prop-naming`]: invert if statement ([#3634][] @HenryBrown0)
* [Refactor] [`function-component-definition`]: exit early if no type params ([#3634][] @HenryBrown0)
* [Refactor] [`jsx-props-no-multi-spaces`]: extract type parameters to var ([#3634][] @HenryBrown0)

[#3638]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3638
[#3634]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3634
[#3633]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3633
[#3630]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3630
[#3623]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3623
Expand Down
27 changes: 16 additions & 11 deletions lib/rules/boolean-prop-naming.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,19 +240,24 @@ module.exports = {
}

if (
component.node.parent
&& component.node.parent.type === 'VariableDeclarator'
&& component.node.parent.id
&& component.node.parent.id.type === 'Identifier'
&& component.node.parent.id.typeAnnotation
&& component.node.parent.id.typeAnnotation.typeAnnotation
&& component.node.parent.id.typeAnnotation.typeAnnotation.typeParameters
&& (
component.node.parent.id.typeAnnotation.typeAnnotation.typeParameters.type === 'TSTypeParameterInstantiation'
|| component.node.parent.id.typeAnnotation.typeAnnotation.typeParameters.type === 'TypeParameterInstantiation'
!component.node.parent
|| component.node.parent.type !== 'VariableDeclarator'
|| !component.node.parent.id
|| component.node.parent.id.type !== 'Identifier'
|| !component.node.parent.id.typeAnnotation
|| !component.node.parent.id.typeAnnotation.typeAnnotation
) {
return;
}

const annotationTypeParams = component.node.parent.id.typeAnnotation.typeAnnotation.typeParameters;
if (
annotationTypeParams && (
annotationTypeParams.type === 'TSTypeParameterInstantiation'
|| annotationTypeParams.type === 'TypeParameterInstantiation'
)
) {
return component.node.parent.id.typeAnnotation.typeAnnotation.typeParameters.params.find(
return annotationTypeParams.params.find(
(param) => param.type === 'TSTypeReference' || param.type === 'GenericTypeAnnotation'
);
}
Expand Down
12 changes: 5 additions & 7 deletions lib/rules/function-component-definition.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,12 @@ const UNNAMED_FUNCTION_TEMPLATES = {
};

function hasOneUnconstrainedTypeParam(node) {
if (node.typeParameters) {
return (
node.typeParameters.params.length === 1
&& !node.typeParameters.params[0].constraint
);
}
const nodeTypeParams = node.typeParameters;

return false;
return nodeTypeParams
&& nodeTypeParams.params
&& nodeTypeParams.params.length === 1
&& !nodeTypeParams.params[0].constraint;
}

function hasName(node) {
Expand Down
8 changes: 6 additions & 2 deletions lib/rules/jsx-props-no-multi-spaces.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,12 @@
}

function containsGenericType(node) {
const containsTypeParams = typeof node.typeParameters !== 'undefined';
return containsTypeParams && node.typeParameters.type === 'TSTypeParameterInstantiation';
const nodeTypeParams = node.typeParameters;
if (typeof nodeTypeParams === 'undefined') {
return false;
}

return nodeTypeParams.type === 'TSTypeParameterInstantiation';

Check warning on line 106 in lib/rules/jsx-props-no-multi-spaces.js

View check run for this annotation

Codecov / codecov/patch

lib/rules/jsx-props-no-multi-spaces.js#L106

Added line #L106 was not covered by tests
ljharb marked this conversation as resolved.
Show resolved Hide resolved
}

function getGenericNode(node) {
Expand Down
24 changes: 14 additions & 10 deletions lib/util/propTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,8 @@
typeName = node.typeName.name;
const leftMostName = getLeftMostTypeName(node.typeName);
const shouldTraverseTypeParams = genericReactTypesImport.has(leftMostName);
if (shouldTraverseTypeParams && node.typeParameters && node.typeParameters.length !== 0) {
const nodeTypeParams = node.typeParameters;
if (shouldTraverseTypeParams && nodeTypeParams && nodeTypeParams.length !== 0) {

Check warning on line 631 in lib/util/propTypes.js

View check run for this annotation

Codecov / codecov/patch

lib/util/propTypes.js#L630-L631

Added lines #L630 - L631 were not covered by tests
ljharb marked this conversation as resolved.
Show resolved Hide resolved
// All react Generic types are derived from:
// type PropsWithChildren<P> = P & { children?: ReactNode | undefined }
// So we should construct an optional children prop
Expand All @@ -638,7 +639,7 @@
const idx = genericTypeParamIndexWherePropsArePresent[
leftMostName !== rightMostName ? rightMostName : importedName
];
const nextNode = node.typeParameters.params[idx];
const nextNode = nodeTypeParams.params[idx];

Check warning on line 642 in lib/util/propTypes.js

View check run for this annotation

Codecov / codecov/patch

lib/util/propTypes.js#L642

Added line #L642 was not covered by tests
this.visitTSNode(nextNode);
return;
}
Expand Down Expand Up @@ -727,9 +728,10 @@

convertReturnTypeToPropTypes(node) {
// ReturnType<T> should always have one parameter
if (node.typeParameters) {
if (node.typeParameters.params.length === 1) {
let returnType = node.typeParameters.params[0];
const nodeTypeParams = node.typeParameters;
if (nodeTypeParams) {
if (nodeTypeParams.params.length === 1) {
let returnType = nodeTypeParams.params[0];

Check warning on line 734 in lib/util/propTypes.js

View check run for this annotation

Codecov / codecov/patch

lib/util/propTypes.js#L731-L734

Added lines #L731 - L734 were not covered by tests
// This line is trying to handle typescript-eslint-parser
// typescript-eslint-parser TSTypeQuery is wrapped by TSTypeReference
if (astUtil.isTSTypeReference(returnType)) {
Expand Down Expand Up @@ -761,8 +763,9 @@
case 'ObjectExpression':
iterateProperties(context, res.properties, (key, value, propNode) => {
if (propNode && propNode.argument && propNode.argument.type === 'CallExpression') {
if (propNode.argument.typeParameters) {
this.visitTSNode(propNode.argument.typeParameters);
const propNodeTypeParams = propNode.argument.typeParameters;
if (propNodeTypeParams) {
this.visitTSNode(propNodeTypeParams);

Check warning on line 768 in lib/util/propTypes.js

View check run for this annotation

Codecov / codecov/patch

lib/util/propTypes.js#L766-L768

Added lines #L766 - L768 were not covered by tests
} else {
// Ignore this CallExpression return value since it doesn't have any typeParameters to let us know it's types.
this.shouldIgnorePropTypes = true;
Expand Down Expand Up @@ -960,8 +963,9 @@
break;
case 'GenericTypeAnnotation':
if (propTypes.id.name === '$ReadOnly') {
const propTypeParams = propTypes.typeParameters;
ignorePropsValidation = declarePropTypesForObjectTypeAnnotation(
propTypes.typeParameters.params[0],
propTypeParams.params[0],
declaredPropTypes
);
} else {
Expand Down Expand Up @@ -1011,9 +1015,9 @@
)
)
) {
const propTypes = node.parent.typeParameters.params[1];
const propTypesParams = node.parent.typeParameters;

Check warning on line 1018 in lib/util/propTypes.js

View check run for this annotation

Codecov / codecov/patch

lib/util/propTypes.js#L1018

Added line #L1018 was not covered by tests
const declaredPropTypes = {};
const obj = new DeclarePropTypesForTSTypeAnnotation(propTypes, declaredPropTypes);
const obj = new DeclarePropTypesForTSTypeAnnotation(propTypesParams.params[1], declaredPropTypes);

Check warning on line 1020 in lib/util/propTypes.js

View check run for this annotation

Codecov / codecov/patch

lib/util/propTypes.js#L1020

Added line #L1020 was not covered by tests
components.set(node, {
declaredPropTypes: obj.declaredPropTypes,
ignorePropsValidation: obj.shouldIgnorePropTypes,
Expand Down