Skip to content

Commit f2176a8

Browse files
committed
Add support for generic types on forwardRef
1 parent ba0eef7 commit f2176a8

1 file changed

Lines changed: 44 additions & 3 deletions

File tree

packages/react-docgen/src/utils/getTypeFromReactComponent.ts

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import type {
1212
FlowType,
1313
InterfaceDeclaration,
1414
InterfaceExtends,
15+
Node,
1516
TSExpressionWithTypeArguments,
1617
TSInterfaceDeclaration,
1718
TSType,
@@ -41,6 +42,20 @@ function getStatelessPropsPath(
4142
return value.get('params')[0];
4243
}
4344

45+
function getForwardRefGenericsType(componentDefinition: NodePath) {
46+
const typeParameters = componentDefinition.get(
47+
'typeParameters',
48+
) as NodePath<Node>;
49+
50+
if (typeParameters && typeParameters.hasNode()) {
51+
const params = typeParameters.get('params') as Array<NodePath<Node>>;
52+
53+
return params[1] ?? null;
54+
}
55+
56+
return null;
57+
}
58+
4459
function findAssignedVariableType(
4560
componentDefinition: NodePath,
4661
): NodePath | null {
@@ -106,6 +121,13 @@ export default (componentDefinition: NodePath): NodePath[] => {
106121
}
107122
}
108123
} else {
124+
const genericTypeAnnotation =
125+
getForwardRefGenericsType(componentDefinition);
126+
127+
if (genericTypeAnnotation) {
128+
typePaths.push(genericTypeAnnotation);
129+
}
130+
109131
const propsParam = getStatelessPropsPath(componentDefinition);
110132

111133
if (propsParam) {
@@ -162,9 +184,28 @@ export function applyToTypeProperties(
162184
(typesPath) =>
163185
applyToTypeProperties(documentation, typesPath, callback, typeParams),
164186
);
165-
} else if (!path.isUnionTypeAnnotation()) {
166-
// The react-docgen output format does not currently allow
167-
// for the expression of union types
187+
} else if (path.isParenthesizedExpression() || path.isTSParenthesizedType()) {
188+
const typeAnnotation = path.get('typeAnnotation');
189+
const typeAnnotationPath = Array.isArray(typeAnnotation)
190+
? typeAnnotation[0]
191+
: typeAnnotation;
192+
193+
if (typeAnnotationPath) {
194+
applyToTypeProperties(
195+
documentation,
196+
typeAnnotationPath,
197+
callback,
198+
typeParams,
199+
);
200+
}
201+
} else if (path.isUnionTypeAnnotation() || path.isTSUnionType()) {
202+
const typeNodes = path.get('types');
203+
const types = Array.isArray(typeNodes) ? typeNodes : [typeNodes];
204+
205+
types.forEach((typesPath) =>
206+
applyToTypeProperties(documentation, typesPath, callback, typeParams),
207+
);
208+
} else {
168209
const typePath = resolveGenericTypeAnnotation(path);
169210

170211
if (typePath) {

0 commit comments

Comments
 (0)