From 6ab61b9af1ac6a7a5d6316374a185a2b96259b08 Mon Sep 17 00:00:00 2001 From: Remo Vetere Date: Fri, 26 Apr 2024 13:43:32 +0200 Subject: [PATCH 1/7] Add support for complex union types --- .../__snapshots__/getTSType-test.ts.snap | 30 +++++ .../src/utils/__tests__/getTSType-test.ts | 20 ++++ packages/react-docgen/src/utils/getTSType.ts | 110 +++++++++++++++++- 3 files changed, 155 insertions(+), 5 deletions(-) diff --git a/packages/react-docgen/src/utils/__tests__/__snapshots__/getTSType-test.ts.snap b/packages/react-docgen/src/utils/__tests__/__snapshots__/getTSType-test.ts.snap index 22e588f60e3..1479e58e7ab 100644 --- a/packages/react-docgen/src/utils/__tests__/__snapshots__/getTSType-test.ts.snap +++ b/packages/react-docgen/src/utils/__tests__/__snapshots__/getTSType-test.ts.snap @@ -125,6 +125,36 @@ exports[`getTSType > can resolve indexed access to imported type 1`] = ` } `; +exports[`getTSType > deep resolve intersection types 1`] = ` +{ + "elements": [ + { + "key": "name", + "value": { + "name": "string", + "required": true, + }, + }, + { + "key": "a", + "value": { + "name": "number", + "required": true, + }, + }, + { + "key": "b", + "value": { + "name": "string", + "required": false, + }, + }, + ], + "name": "intersection", + "raw": "{ name: string } & (MyType | MySecondType)", +} +`; + exports[`getTSType > detects array type 1`] = ` { "elements": [ diff --git a/packages/react-docgen/src/utils/__tests__/getTSType-test.ts b/packages/react-docgen/src/utils/__tests__/getTSType-test.ts index 0413d2b8503..9e4659d3146 100644 --- a/packages/react-docgen/src/utils/__tests__/getTSType-test.ts +++ b/packages/react-docgen/src/utils/__tests__/getTSType-test.ts @@ -70,6 +70,12 @@ const mockImporter = makeMockImporter({ true, ).get('declaration') as NodePath, + MySecondType: (stmtLast) => + stmtLast( + `export type MySecondType = { a: number, b?: never };`, + true, + ).get('declaration') as NodePath, + MyGenericType: (stmtLast) => stmtLast( `export type MyGenericType = { a: T, b: Array };`, @@ -501,6 +507,20 @@ describe('getTSType', () => { expect(getTSType(typePath)).toMatchSnapshot(); }); + test('deep resolve intersection types', () => { + const typePath = typeAlias( + ` + const x: SuperType = {}; + import { MyType } from 'MyType'; + import { MySecondType } from 'MySecondType'; + type SuperType = { name: string } & (MyType | MySecondType); + `, + mockImporter, + ); + + expect(getTSType(typePath)).toMatchSnapshot(); + }); + test('resolves typeof of import type', () => { const typePath = typeAlias( "var x: typeof import('MyType') = {};", diff --git a/packages/react-docgen/src/utils/getTSType.ts b/packages/react-docgen/src/utils/getTSType.ts index c938bf9470b..c86e380f669 100644 --- a/packages/react-docgen/src/utils/getTSType.ts +++ b/packages/react-docgen/src/utils/getTSType.ts @@ -36,6 +36,7 @@ import type { TypeScript, TSQualifiedName, TSLiteralType, + TSParenthesizedType, } from '@babel/types'; import { getDocblock } from './docblock.js'; @@ -69,6 +70,7 @@ const namedTypes: Record< TSUnionType: handleTSUnionType, TSFunctionType: handleTSFunctionType, TSIntersectionType: handleTSIntersectionType, + TSParenthesizedType: handleTSParenthesizedType, TSMappedType: handleTSMappedType, TSTupleType: handleTSTupleType, TSTypeQuery: handleTSTypeQuery, @@ -127,8 +129,7 @@ function handleTSTypeReference( } const resolvedPath = - (typeParams && typeParams[type.name]) || - resolveToValue(path.get('typeName')); + (typeParams && typeParams[type.name]) || resolveToValue(typeName); const typeParameters = path.get('typeParameters'); const resolvedTypeParameters = resolvedPath.get('typeParameters') as NodePath< @@ -267,19 +268,118 @@ function handleTSUnionType( }; } +function handleTSParenthesizedType( + path: NodePath, + typeParams: TypeParameters | null, +): ElementsType { + const innerTypePath = path.get('typeAnnotation'); + + // Resolve the type inside the parentheses using your existing function + const resolvedType = getTSTypeWithResolvedTypes(innerTypePath, typeParams); + + return { + name: 'parenthesized', + raw: printValue(path), + elements: Array.isArray(resolvedType) ? resolvedType : [resolvedType], + }; +} + +interface PropertyWithKey { + key: TypeDescriptor | string; + value: TypeDescriptor; + description?: string | undefined; +} + function handleTSIntersectionType( path: NodePath, typeParams: TypeParameters | null, ): ElementsType { + const resolvedTypes = path + .get('types') + .map((subTypePath) => getTSTypeWithResolvedTypes(subTypePath, typeParams)); + + let elements: Array> = []; + + resolvedTypes.forEach((resolvedType) => { + switch (resolvedType.name) { + default: + case 'signature': + elements.push(resolvedType); + break; + case 'parenthesized': { + if ('elements' in resolvedType && resolvedType.elements[0]) { + const firstElement = resolvedType.elements[0]; + + if (firstElement && 'elements' in firstElement) { + elements = [...elements, ...firstElement.elements]; + } + } + break; + } + } + }); + + const elementsDedup: PropertyWithKey[] = []; + const forbiddenTypes = ['unknown', 'never']; + + // dedup elements + elements.forEach((element) => { + if (hasSignature(element)) { + const { signature } = element; + + if (hasProperties(signature)) { + signature.properties.forEach((property) => { + const existingIndex = elementsDedup.findIndex( + (e) => e.key === property.key, + ); + + if (existingIndex === -1) { + elementsDedup.push(property); + } else { + // If the element is already in the array, we need to merge the properties + const existingProperty = elementsDedup[existingIndex]; + + if (existingProperty) { + elementsDedup[existingIndex] = { + key: property.key, + value: { + name: forbiddenTypes.includes(property.value.name) + ? existingProperty.value.name + : property.value.name, + required: + property.value.required === false + ? false + : existingProperty.value.required, + }, + }; + } + } + }); + } + } else { + elementsDedup.push(element as unknown as PropertyWithKey); + } + }); + return { name: 'intersection', raw: printValue(path), - elements: path - .get('types') - .map((subType) => getTSTypeWithResolvedTypes(subType, typeParams)), + elements: elementsDedup as unknown as Array< + TypeDescriptor + >, }; } +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function hasSignature(element: any): element is { signature: unknown } { + return 'signature' in element; +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function hasProperties(element: any): element is { properties: unknown } { + return 'properties' in element; +} + // type OptionsFlags = { [Property in keyof Type]; }; function handleTSMappedType( path: NodePath, From 8c654b0037bb8961a50640cb4c93f70df9b427ff Mon Sep 17 00:00:00 2001 From: Remo Vetere Date: Fri, 26 Apr 2024 13:44:56 +0200 Subject: [PATCH 2/7] Cleanup --- packages/react-docgen/src/utils/getTSType.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/react-docgen/src/utils/getTSType.ts b/packages/react-docgen/src/utils/getTSType.ts index c86e380f669..af4a92aad69 100644 --- a/packages/react-docgen/src/utils/getTSType.ts +++ b/packages/react-docgen/src/utils/getTSType.ts @@ -273,8 +273,6 @@ function handleTSParenthesizedType( typeParams: TypeParameters | null, ): ElementsType { const innerTypePath = path.get('typeAnnotation'); - - // Resolve the type inside the parentheses using your existing function const resolvedType = getTSTypeWithResolvedTypes(innerTypePath, typeParams); return { From 33ad337046372da437deda7816302a5aeffab20d Mon Sep 17 00:00:00 2001 From: Remo Vetere Date: Mon, 29 Apr 2024 12:52:39 +0200 Subject: [PATCH 3/7] Support union prop types in react components --- .../__tests__/codeTypeHandler-test.ts | 21 ++++++++++++++-- .../src/utils/getTypeFromReactComponent.ts | 25 ++++++++++++++++--- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/packages/react-docgen/src/handlers/__tests__/codeTypeHandler-test.ts b/packages/react-docgen/src/handlers/__tests__/codeTypeHandler-test.ts index 3bdfb497269..2f910688709 100644 --- a/packages/react-docgen/src/handlers/__tests__/codeTypeHandler-test.ts +++ b/packages/react-docgen/src/handlers/__tests__/codeTypeHandler-test.ts @@ -262,7 +262,7 @@ describe('codeTypeHandler', () => { expect(documentation.descriptors).toMatchSnapshot(); }); - test('does not support union proptypes', () => { + test('does support union proptypes', () => { const definition = parse .statement( `(props: Props) =>
; @@ -274,7 +274,24 @@ describe('codeTypeHandler', () => { .get('expression') as NodePath; expect(() => codeTypeHandler(documentation, definition)).not.toThrow(); - expect(documentation.descriptors).toEqual({}); + expect(documentation.descriptors).toEqual({ + bar: { + required: true, + flowType: { + name: 'literal', + value: "'barValue'", + }, + description: '', + }, + foo: { + required: true, + flowType: { + name: 'literal', + value: "'fooValue'", + }, + description: '', + }, + }); }); describe('imported prop types', () => { diff --git a/packages/react-docgen/src/utils/getTypeFromReactComponent.ts b/packages/react-docgen/src/utils/getTypeFromReactComponent.ts index b0241c121a0..b1c7f8e87ca 100644 --- a/packages/react-docgen/src/utils/getTypeFromReactComponent.ts +++ b/packages/react-docgen/src/utils/getTypeFromReactComponent.ts @@ -162,9 +162,28 @@ export function applyToTypeProperties( (typesPath) => applyToTypeProperties(documentation, typesPath, callback, typeParams), ); - } else if (!path.isUnionTypeAnnotation()) { - // The react-docgen output format does not currently allow - // for the expression of union types + } else if (path.isParenthesizedExpression() || path.isTSParenthesizedType()) { + const typeAnnotation = path.get('typeAnnotation'); + const typeAnnotationPath = Array.isArray(typeAnnotation) + ? typeAnnotation[0] + : typeAnnotation; + + if (typeAnnotationPath) { + applyToTypeProperties( + documentation, + typeAnnotationPath, + callback, + typeParams, + ); + } + } else if (path.isUnionTypeAnnotation() || path.isTSUnionType()) { + const typeNodes = path.get('types'); + const types = Array.isArray(typeNodes) ? typeNodes : [typeNodes]; + + types.forEach((typesPath) => + applyToTypeProperties(documentation, typesPath, callback, typeParams), + ); + } else { const typePath = resolveGenericTypeAnnotation(path); if (typePath) { From 79bc1395d13e762e65be4059f775bd571694da7b Mon Sep 17 00:00:00 2001 From: Remo Vetere Date: Tue, 30 Apr 2024 09:21:58 +0200 Subject: [PATCH 4/7] Add utility to merge types --- .../src/handlers/codeTypeHandler.ts | 21 +++++- packages/react-docgen/src/utils/getTSType.ts | 18 ++--- .../src/utils/mergeTSIntersectionTypes.ts | 65 +++++++++++++++++++ 3 files changed, 90 insertions(+), 14 deletions(-) create mode 100644 packages/react-docgen/src/utils/mergeTSIntersectionTypes.ts diff --git a/packages/react-docgen/src/handlers/codeTypeHandler.ts b/packages/react-docgen/src/handlers/codeTypeHandler.ts index 75310b4b3d8..8745912418e 100644 --- a/packages/react-docgen/src/handlers/codeTypeHandler.ts +++ b/packages/react-docgen/src/handlers/codeTypeHandler.ts @@ -13,6 +13,7 @@ import type { NodePath } from '@babel/traverse'; import type { FlowType } from '@babel/types'; import type { ComponentNode } from '../resolver/index.js'; import type { Handler } from './index.js'; +import mergeTSIntersectionTypes from '../utils/mergeTSIntersectionTypes.js'; function setPropDescriptor( documentation: Documentation, @@ -87,8 +88,24 @@ function setPropDescriptor( const propDescriptor = documentation.getPropDescriptor(propName); - propDescriptor.required = !path.node.optional; - propDescriptor.tsType = type; + if (propDescriptor.tsType) { + const mergedType = mergeTSIntersectionTypes( + { + name: type.name, + required: !path.node.optional, + }, + { + name: propDescriptor.tsType.name, + required: propDescriptor.required, + }, + ); + + propDescriptor.tsType.name = mergedType.name; + propDescriptor.required = mergedType.required; + } else { + propDescriptor.tsType = type; + propDescriptor.required = !path.node.optional; + } // We are doing this here instead of in a different handler // to not need to duplicate the logic for checking for diff --git a/packages/react-docgen/src/utils/getTSType.ts b/packages/react-docgen/src/utils/getTSType.ts index af4a92aad69..30dc0bbd5cb 100644 --- a/packages/react-docgen/src/utils/getTSType.ts +++ b/packages/react-docgen/src/utils/getTSType.ts @@ -39,6 +39,7 @@ import type { TSParenthesizedType, } from '@babel/types'; import { getDocblock } from './docblock.js'; +import mergeTSIntersectionTypes from './mergeTSIntersectionTypes.js'; const tsTypes: Record = { TSAnyKeyword: 'any', @@ -318,7 +319,6 @@ function handleTSIntersectionType( }); const elementsDedup: PropertyWithKey[] = []; - const forbiddenTypes = ['unknown', 'never']; // dedup elements elements.forEach((element) => { @@ -328,27 +328,21 @@ function handleTSIntersectionType( if (hasProperties(signature)) { signature.properties.forEach((property) => { const existingIndex = elementsDedup.findIndex( - (e) => e.key === property.key, + ({ key }) => key === property.key, ); if (existingIndex === -1) { elementsDedup.push(property); } else { - // If the element is already in the array, we need to merge the properties const existingProperty = elementsDedup[existingIndex]; if (existingProperty) { elementsDedup[existingIndex] = { key: property.key, - value: { - name: forbiddenTypes.includes(property.value.name) - ? existingProperty.value.name - : property.value.name, - required: - property.value.required === false - ? false - : existingProperty.value.required, - }, + value: mergeTSIntersectionTypes( + property.value, + existingProperty.value, + ), }; } } diff --git a/packages/react-docgen/src/utils/mergeTSIntersectionTypes.ts b/packages/react-docgen/src/utils/mergeTSIntersectionTypes.ts new file mode 100644 index 00000000000..cf921479c3e --- /dev/null +++ b/packages/react-docgen/src/utils/mergeTSIntersectionTypes.ts @@ -0,0 +1,65 @@ +import type { + TSFunctionSignatureType, + TypeDescriptor, +} from '../Documentation.js'; + +/** + * Merges two TSFunctionSignatureType types into one. + * + * @example + * const existingType = { + * "key": "children", + * "value": { + * "name": "ReactNode", + * "required": true, + * }, + * }; + * const newType = { + * "key": "children", + * "value": { + * "name": "never", + * "required": false, + * }, + * }; + * + * return { + * "key": "children", + * "value": { + * "name": "ReactNode", + * "required": false, + * }, + * }; + */ +export default ( + newType: TypeDescriptor, + existingType: TypeDescriptor, +): TypeDescriptor => { + const newTypeIsForbiddenToUse = ['never'].includes(newType.name); + + if (newTypeIsForbiddenToUse) { + let mergedType = { + ...existingType, + required: + newType.required === false || existingType.required === false + ? false + : existingType.required, + }; + + if ('nullable' in existingType) { + mergedType = { + ...mergedType, + nullable: newType.nullable === true ? true : existingType.nullable, + }; + } + + return mergedType; + } + + return { + ...newType, + required: + newType.required === false || existingType.required === false + ? false + : existingType.required, + }; +}; From 38e2bc0a454deee708cdc43966df7b5ea56620c2 Mon Sep 17 00:00:00 2001 From: Remo Vetere Date: Mon, 13 May 2024 17:05:15 +0200 Subject: [PATCH 5/7] Finalize merge logic and add more tests --- .../codeTypeHandler-test.ts.snap | 2 +- .../src/handlers/codeTypeHandler.ts | 9 +-- .../mergeTSIntersectionTypes-test.ts | 76 +++++++++++++++++++ packages/react-docgen/src/utils/getTSType.ts | 2 +- .../src/utils/mergeTSIntersectionTypes.ts | 39 +++++----- 5 files changed, 99 insertions(+), 29 deletions(-) create mode 100644 packages/react-docgen/src/utils/__tests__/mergeTSIntersectionTypes-test.ts diff --git a/packages/react-docgen/src/handlers/__tests__/__snapshots__/codeTypeHandler-test.ts.snap b/packages/react-docgen/src/handlers/__tests__/__snapshots__/codeTypeHandler-test.ts.snap index 58dfd645a8c..feb9fe95148 100644 --- a/packages/react-docgen/src/handlers/__tests__/__snapshots__/codeTypeHandler-test.ts.snap +++ b/packages/react-docgen/src/handlers/__tests__/__snapshots__/codeTypeHandler-test.ts.snap @@ -1655,7 +1655,7 @@ exports[`codeTypeHandler > stateless TS component and variable type takes preced "description": "", "required": true, "tsType": { - "name": "string", + "name": "number | string", }, }, } diff --git a/packages/react-docgen/src/handlers/codeTypeHandler.ts b/packages/react-docgen/src/handlers/codeTypeHandler.ts index 8745912418e..f008a9ba8e7 100644 --- a/packages/react-docgen/src/handlers/codeTypeHandler.ts +++ b/packages/react-docgen/src/handlers/codeTypeHandler.ts @@ -81,7 +81,6 @@ function setPropDescriptor( return; } const type = getTSType(typeAnnotation, typeParams); - const propName = getPropertyName(path); if (!propName) return; @@ -90,14 +89,14 @@ function setPropDescriptor( if (propDescriptor.tsType) { const mergedType = mergeTSIntersectionTypes( - { - name: type.name, - required: !path.node.optional, - }, { name: propDescriptor.tsType.name, required: propDescriptor.required, }, + { + name: type.name, + required: !path.node.optional, + }, ); propDescriptor.tsType.name = mergedType.name; diff --git a/packages/react-docgen/src/utils/__tests__/mergeTSIntersectionTypes-test.ts b/packages/react-docgen/src/utils/__tests__/mergeTSIntersectionTypes-test.ts new file mode 100644 index 00000000000..1430aa12b92 --- /dev/null +++ b/packages/react-docgen/src/utils/__tests__/mergeTSIntersectionTypes-test.ts @@ -0,0 +1,76 @@ +import { describe, expect, test } from 'vitest'; +import mergeTSIntersectionTypes from '../mergeTSIntersectionTypes.js'; + +describe('mergeTSIntersectionTypes', () => { + test('it merges two types correctly', () => { + const mergedType = mergeTSIntersectionTypes( + { + name: 'string', + required: true, + }, + { + name: 'number', + required: true, + }, + ); + + expect(mergedType).toEqual({ + name: 'string | number', + required: true, + }); + }); + + test('it ignores types of "never"', () => { + const mergedType = mergeTSIntersectionTypes( + { + name: 'string', + required: true, + }, + { + name: 'never', + required: true, + }, + ); + + expect(mergedType).toEqual({ + name: 'string', + required: true, + }); + }); + + test('if one of the types is "unknown", it overrides all other types', () => { + const mergedType = mergeTSIntersectionTypes( + { + name: 'string', + required: true, + }, + { + name: 'unknown', + required: true, + }, + ); + + expect(mergedType).toEqual({ + name: 'unknown', + required: true, + }); + }); + + test('if one of the types is NOT required, the merged one is NOT required too', () => { + const mergedType = mergeTSIntersectionTypes( + { + name: 'string', + required: true, + }, + { + name: 'number', + required: false, + }, + ); + + expect(mergedType).toEqual({ + name: 'string | number', + required: false, + }); + }); +}); diff --git a/packages/react-docgen/src/utils/getTSType.ts b/packages/react-docgen/src/utils/getTSType.ts index 30dc0bbd5cb..d1f2fd80fbf 100644 --- a/packages/react-docgen/src/utils/getTSType.ts +++ b/packages/react-docgen/src/utils/getTSType.ts @@ -340,8 +340,8 @@ function handleTSIntersectionType( elementsDedup[existingIndex] = { key: property.key, value: mergeTSIntersectionTypes( - property.value, existingProperty.value, + property.value, ), }; } diff --git a/packages/react-docgen/src/utils/mergeTSIntersectionTypes.ts b/packages/react-docgen/src/utils/mergeTSIntersectionTypes.ts index cf921479c3e..41a88ab64b3 100644 --- a/packages/react-docgen/src/utils/mergeTSIntersectionTypes.ts +++ b/packages/react-docgen/src/utils/mergeTSIntersectionTypes.ts @@ -31,35 +31,30 @@ import type { * }; */ export default ( - newType: TypeDescriptor, existingType: TypeDescriptor, + newType: TypeDescriptor, ): TypeDescriptor => { - const newTypeIsForbiddenToUse = ['never'].includes(newType.name); + const required = + newType.required === false || existingType.required === false + ? false + : existingType.required; - if (newTypeIsForbiddenToUse) { - let mergedType = { - ...existingType, - required: - newType.required === false || existingType.required === false - ? false - : existingType.required, - }; + const existingTypesArray = existingType.name.split('|').map((t) => t.trim()); + const existingTypes = new Set(existingTypesArray); - if ('nullable' in existingType) { - mergedType = { - ...mergedType, - nullable: newType.nullable === true ? true : existingType.nullable, - }; - } + if (!['never'].includes(newType.name)) { + existingTypes.add(newType.name); + } - return mergedType; + if (existingType.name === 'unknown' || newType.name === 'unknown') { + return { + name: 'unknown', + required, + }; } return { - ...newType, - required: - newType.required === false || existingType.required === false - ? false - : existingType.required, + name: Array.from(existingTypes).join(' | '), + required, }; }; From a8d4b25765ad8703cec56c0a50f4e17a989d724b Mon Sep 17 00:00:00 2001 From: Remo Vetere Date: Mon, 27 May 2024 13:04:26 +0200 Subject: [PATCH 6/7] Add support for generic types on forwardRef --- .../src/utils/getTypeFromReactComponent.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/packages/react-docgen/src/utils/getTypeFromReactComponent.ts b/packages/react-docgen/src/utils/getTypeFromReactComponent.ts index b1c7f8e87ca..0c057fa769b 100644 --- a/packages/react-docgen/src/utils/getTypeFromReactComponent.ts +++ b/packages/react-docgen/src/utils/getTypeFromReactComponent.ts @@ -12,6 +12,7 @@ import type { FlowType, InterfaceDeclaration, InterfaceExtends, + Node, TSExpressionWithTypeArguments, TSInterfaceDeclaration, TSType, @@ -41,6 +42,17 @@ function getStatelessPropsPath( return value.get('params')[0]; } +function getForwardRefGenericsType(componentDefinition: NodePath) { + const typeParameters = componentDefinition.get( + 'typeParameters', + ) as NodePath; + if (typeParameters && typeParameters.hasNode()) { + const params = typeParameters.get('params') as NodePath[]; + return params[1] ?? null; + } + return null; +} + function findAssignedVariableType( componentDefinition: NodePath, ): NodePath | null { @@ -106,6 +118,11 @@ export default (componentDefinition: NodePath): NodePath[] => { } } } else { + const typeAnnotation = getForwardRefGenericsType(componentDefinition); + if (typeAnnotation) { + typePaths.push(typeAnnotation); + } + const propsParam = getStatelessPropsPath(componentDefinition); if (propsParam) { From d75b4847951e5434022f786b05c4f1320bea01a0 Mon Sep 17 00:00:00 2001 From: Remo Vetere Date: Mon, 27 May 2024 19:31:13 +0200 Subject: [PATCH 7/7] Do not mix changes --- .../src/utils/getTypeFromReactComponent.ts | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/packages/react-docgen/src/utils/getTypeFromReactComponent.ts b/packages/react-docgen/src/utils/getTypeFromReactComponent.ts index 0c057fa769b..b1c7f8e87ca 100644 --- a/packages/react-docgen/src/utils/getTypeFromReactComponent.ts +++ b/packages/react-docgen/src/utils/getTypeFromReactComponent.ts @@ -12,7 +12,6 @@ import type { FlowType, InterfaceDeclaration, InterfaceExtends, - Node, TSExpressionWithTypeArguments, TSInterfaceDeclaration, TSType, @@ -42,17 +41,6 @@ function getStatelessPropsPath( return value.get('params')[0]; } -function getForwardRefGenericsType(componentDefinition: NodePath) { - const typeParameters = componentDefinition.get( - 'typeParameters', - ) as NodePath; - if (typeParameters && typeParameters.hasNode()) { - const params = typeParameters.get('params') as NodePath[]; - return params[1] ?? null; - } - return null; -} - function findAssignedVariableType( componentDefinition: NodePath, ): NodePath | null { @@ -118,11 +106,6 @@ export default (componentDefinition: NodePath): NodePath[] => { } } } else { - const typeAnnotation = getForwardRefGenericsType(componentDefinition); - if (typeAnnotation) { - typePaths.push(typeAnnotation); - } - const propsParam = getStatelessPropsPath(componentDefinition); if (propsParam) {