From bf68a56e61858cb8daa27ce08c96a5b628c6a626 Mon Sep 17 00:00:00 2001 From: Daniel Tschinder <231804+danez@users.noreply.github.com> Date: Fri, 22 Dec 2023 12:10:23 +0100 Subject: [PATCH 1/2] Refactor code to prepare for future support of enums for example --- packages/react-docgen/src/utils/getTSType.ts | 37 ++++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/packages/react-docgen/src/utils/getTSType.ts b/packages/react-docgen/src/utils/getTSType.ts index c938bf9470b..311bbf5a8fc 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, + TSTypeAliasDeclaration, } from '@babel/types'; import { getDocblock } from './docblock.js'; @@ -54,6 +55,8 @@ const tsTypes: Record = { TSVoidKeyword: 'void', }; +const UNKNOWN_TYPE = Object.freeze({ name: 'unknown' }) as SimpleType; + const namedTypes: Record< string, ( @@ -71,6 +74,7 @@ const namedTypes: Record< TSIntersectionType: handleTSIntersectionType, TSMappedType: handleTSMappedType, TSTupleType: handleTSTupleType, + TSTypeAliasDeclaration: handleTSTypeAliasDeclaration, TSTypeQuery: handleTSTypeQuery, TSTypeOperator: handleTSTypeOperator, TSIndexedAccessType: handleTSIndexedAccessType, @@ -113,6 +117,15 @@ function handleTSArrayType( }; } +function handleTSTypeAliasDeclaration( + path: NodePath, + typeParams: TypeParameters | null, +): TypeDescriptor { + const resolvedTypeAnnotation = path.get('typeAnnotation'); + + return getTSTypeWithResolvedTypes(resolvedTypeAnnotation, typeParams); +} + function handleTSTypeReference( path: NodePath, typeParams: TypeParameters | null, @@ -127,8 +140,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< @@ -149,15 +161,18 @@ function handleTSTypeReference( resolvedPath as NodePath, null, ); - } + } else if (resolvedPath !== typeName) { + const resolvedType = getTSTypeWithResolvedTypes( + resolvedPath as NodePath, + typeParams, + ); - const resolvedTypeAnnotation = resolvedPath.get('typeAnnotation') as NodePath< - TSType | TSTypeAnnotation | null | undefined - >; + if (resolvedType !== UNKNOWN_TYPE) { + return resolvedType; + } + } - if (resolvedTypeAnnotation.hasNode()) { - type = getTSTypeWithResolvedTypes(resolvedTypeAnnotation, typeParams); - } else if (typeParameters.hasNode()) { + if (typeParameters.hasNode()) { const params = typeParameters.get('params'); type = { @@ -479,7 +494,7 @@ function handleTSIndexedAccessType( }); if (!resolvedType) { - return { name: 'unknown' }; + return UNKNOWN_TYPE; } return { @@ -533,7 +548,7 @@ function getTSTypeWithResolvedTypes( } if (!type) { - type = { name: 'unknown' }; + type = UNKNOWN_TYPE; } if (typeAliasName) { From 86d0d07adc1b51f29b5c33f094954ff2e3aed2f0 Mon Sep 17 00:00:00 2001 From: Daniel Tschinder <231804+danez@users.noreply.github.com> Date: Mon, 11 Mar 2024 15:15:08 +0100 Subject: [PATCH 2/2] Add new experimental features config for upcoming features This way we do not have to do major releases that often and could also iterate more on some options. --- packages/react-docgen/src/config.ts | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/packages/react-docgen/src/config.ts b/packages/react-docgen/src/config.ts index 19eb6263210..5abacccd640 100644 --- a/packages/react-docgen/src/config.ts +++ b/packages/react-docgen/src/config.ts @@ -22,6 +22,10 @@ import { FindExportedDefinitionsResolver, } from './resolver/index.js'; +interface Features { + resolveEnums?: boolean; +} + export interface Config { handlers?: Handler[]; importer?: Importer; @@ -33,6 +37,7 @@ export interface Config { */ filename?: string; babelOptions?: TransformOptions; + experimentalFeatures?: Features; } export type InternalConfig = Omit, 'filename'>; @@ -61,14 +66,26 @@ export const defaultHandlers: Handler[] = [ componentMethodsJsDocHandler, ]; +const defaultFeatures: Required = { + resolveEnums: false, +}; + export function createConfig(inputConfig: Config): InternalConfig { - const { babelOptions, filename, handlers, importer, resolver } = inputConfig; + const { + babelOptions, + filename, + experimentalFeatures, + handlers, + importer, + resolver, + } = inputConfig; const config = { babelOptions: { ...babelOptions }, handlers: handlers ?? defaultHandlers, importer: importer ?? defaultImporter, resolver: resolver ?? defaultResolver, + experimentalFeatures: { ...defaultFeatures, ...experimentalFeatures }, }; if (filename) {