From 291d1bc4647cc22168775b639949c583f937273e Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Sun, 21 Jul 2024 21:40:14 -0700 Subject: [PATCH 1/2] Avoid typescript-eslint deprecation warnings about typeParameters renamed to typeArguments --- lib/util/propTypes.js | 58 +++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 22 deletions(-) diff --git a/lib/util/propTypes.js b/lib/util/propTypes.js index 9450f9222f..93de1f840a 100644 --- a/lib/util/propTypes.js +++ b/lib/util/propTypes.js @@ -41,7 +41,8 @@ function isFunctionType(node) { */ function isSuperTypeParameterPropsDeclaration(node) { if (node && (node.type === 'ClassDeclaration' || node.type === 'ClassExpression')) { - if (node.superTypeParameters && node.superTypeParameters.params.length > 0) { + const superTypeArguments = 'superTypeArguments' in node ? node.superTypeArguments : node.superTypeParameters; + if (superTypeArguments && superTypeArguments.params.length > 0) { return true; } } @@ -581,6 +582,19 @@ module.exports = function propTypesInstructions(context, components, utils) { ); } + /** + * Avoid deprecation errors around referencing typeParameters, while also + * maintain backwards-compatibility after typescript-eslint renamed + * `typeParameters` to `typeArguments` + * https://typescript-eslint.io/troubleshooting/faqs/general/#the-key-property-is-deprecated-on-type-nodes-use-key-instead-warnings + * @param {ASTNode} node The AST node being checked. + * @returns {string | undefined} + */ + function getNodeTypeArguments(node) { + if (!node) return; + return 'typeArguments' in node ? node.typeArguments : node.typeParameters; + } + class DeclarePropTypesForTSTypeAnnotation { constructor(propTypes, declaredPropTypes, rootNode) { this.propTypes = propTypes; @@ -637,8 +651,8 @@ module.exports = function propTypesInstructions(context, components, utils) { typeName = node.typeName.name; const leftMostName = getLeftMostTypeName(node.typeName); const shouldTraverseTypeParams = genericReactTypesImport.has(leftMostName); - const nodeTypeParams = node.typeParameters; - if (shouldTraverseTypeParams && nodeTypeParams && nodeTypeParams.length !== 0) { + const nodeTypeArgs = getNodeTypeArguments(node); + if (shouldTraverseTypeParams && nodeTypeArgs && nodeTypeArgs.length !== 0) { // All react Generic types are derived from: // type PropsWithChildren

= P & { children?: ReactNode | undefined } // So we should construct an optional children prop @@ -660,7 +674,7 @@ module.exports = function propTypesInstructions(context, components, utils) { const idx = genericTypeParamIndexWherePropsArePresent[ leftMostName !== rightMostName ? rightMostName : importedName ]; - const nextNode = nodeTypeParams.params[idx]; + const nextNode = nodeTypeArgs.params[idx]; this.visitTSNode(nextNode); return; } @@ -749,10 +763,10 @@ module.exports = function propTypesInstructions(context, components, utils) { convertReturnTypeToPropTypes(node, rootNode) { // ReturnType should always have one parameter - const nodeTypeParams = node.typeParameters; - if (nodeTypeParams) { - if (nodeTypeParams.params.length === 1) { - let returnType = nodeTypeParams.params[0]; + const nodeTypeArgs = getNodeTypeArguments(node); + if (nodeTypeArgs) { + if (nodeTypeArgs.params.length === 1) { + let returnType = nodeTypeArgs.params[0]; // This line is trying to handle typescript-eslint-parser // typescript-eslint-parser TSTypeQuery is wrapped by TSTypeReference if (astUtil.isTSTypeReference(returnType)) { @@ -784,11 +798,11 @@ module.exports = function propTypesInstructions(context, components, utils) { case 'ObjectExpression': iterateProperties(context, res.properties, (key, value, propNode) => { if (propNode && propNode.argument && propNode.argument.type === 'CallExpression') { - const propNodeTypeParams = propNode.argument.typeParameters; - if (propNodeTypeParams) { - this.visitTSNode(propNodeTypeParams); + const propNodeTypeArgs = getNodeTypeArguments(propNode.argument); + if (propNodeTypeArgs) { + this.visitTSNode(propNodeTypeArgs); } else { - // Ignore this CallExpression return value since it doesn't have any typeParameters to let us know it's types. + // Ignore this CallExpression return value since it doesn't have any typeArguments to let us know it's types. this.shouldIgnorePropTypes = true; return; } @@ -806,10 +820,10 @@ module.exports = function propTypesInstructions(context, components, utils) { }); break; case 'CallExpression': - if (res.typeParameters) { - this.visitTSNode(res.typeParameters); + if (getNodeTypeArguments(res)) { + this.visitTSNode(getNodeTypeArguments(res)); } else { - // Ignore this CallExpression return value since it doesn't have any typeParameters to let us know it's types. + // Ignore this CallExpression return value since it doesn't have any typeArguments to let us know it's types. this.shouldIgnorePropTypes = true; } break; @@ -992,9 +1006,9 @@ module.exports = function propTypesInstructions(context, components, utils) { break; case 'GenericTypeAnnotation': if (propTypes.id.name === '$ReadOnly') { - const propTypeParams = propTypes.typeParameters; + const propTypeArgs = getNodeTypeArguments(propTypes); ignorePropsValidation = declarePropTypesForObjectTypeAnnotation( - propTypeParams.params[0], + propTypeArgs.params[0], declaredPropTypes ); } else { @@ -1034,8 +1048,8 @@ module.exports = function propTypesInstructions(context, components, utils) { if ( node.parent && node.parent.callee - && node.parent.typeParameters - && node.parent.typeParameters.params + && getNodeTypeArguments(node.parent) + && getNodeTypeArguments(node.parent).params && ( node.parent.callee.name === 'forwardRef' || ( node.parent.callee.object @@ -1045,9 +1059,9 @@ module.exports = function propTypesInstructions(context, components, utils) { ) ) ) { - const propTypesParams = node.parent.typeParameters; + const propTypesArguments = getNodeTypeArguments(node.parent); const declaredPropTypes = {}; - const obj = new DeclarePropTypesForTSTypeAnnotation(propTypesParams.params[1], declaredPropTypes, rootNode); + const obj = new DeclarePropTypesForTSTypeAnnotation(propTypesArguments.params[1], declaredPropTypes, rootNode); components.set(node, { declaredPropTypes: obj.declaredPropTypes, ignorePropsValidation: obj.shouldIgnorePropTypes, @@ -1093,7 +1107,7 @@ module.exports = function propTypesInstructions(context, components, utils) { if ( annotation && annotation.type !== 'TSTypeReference' - && annotation.typeParameters == null + && getNodeTypeArguments(annotation) == null ) { return; } From 7feb778ae9fadca79d38064e3f37d3e903e4d921 Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Sun, 21 Jul 2024 23:39:14 -0700 Subject: [PATCH 2/2] Remove incorrect type annotation --- lib/util/propTypes.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/util/propTypes.js b/lib/util/propTypes.js index 93de1f840a..10bf26c0c8 100644 --- a/lib/util/propTypes.js +++ b/lib/util/propTypes.js @@ -588,7 +588,7 @@ module.exports = function propTypesInstructions(context, components, utils) { * `typeParameters` to `typeArguments` * https://typescript-eslint.io/troubleshooting/faqs/general/#the-key-property-is-deprecated-on-type-nodes-use-key-instead-warnings * @param {ASTNode} node The AST node being checked. - * @returns {string | undefined} + * @returns {any | undefined} Type parameters or arguments */ function getNodeTypeArguments(node) { if (!node) return; @@ -652,7 +652,7 @@ module.exports = function propTypesInstructions(context, components, utils) { const leftMostName = getLeftMostTypeName(node.typeName); const shouldTraverseTypeParams = genericReactTypesImport.has(leftMostName); const nodeTypeArgs = getNodeTypeArguments(node); - if (shouldTraverseTypeParams && nodeTypeArgs && nodeTypeArgs.length !== 0) { + if (shouldTraverseTypeParams && nodeTypeArgs && nodeTypeArgs.params.length !== 0) { // All react Generic types are derived from: // type PropsWithChildren

= P & { children?: ReactNode | undefined } // So we should construct an optional children prop