From d742e9efb916eafa1ec030e7d3cc52e7a6bd1352 Mon Sep 17 00:00:00 2001 From: Daniel Tschinder <231804+danez@users.noreply.github.com> Date: Fri, 23 Jun 2023 14:27:14 +0200 Subject: [PATCH] read dockblock from nested flow object types --- .changeset/short-squids-knock.md | 5 ++ .../__snapshots__/getFlowType-test.ts.snap | 60 +++++++++++++++++++ .../src/utils/__tests__/getFlowType-test.ts | 28 +++++---- .../react-docgen/src/utils/getFlowType.ts | 23 +++++-- 4 files changed, 101 insertions(+), 15 deletions(-) create mode 100644 .changeset/short-squids-knock.md diff --git a/.changeset/short-squids-knock.md b/.changeset/short-squids-knock.md new file mode 100644 index 00000000000..ce71ec0e922 --- /dev/null +++ b/.changeset/short-squids-knock.md @@ -0,0 +1,5 @@ +--- +'react-docgen': patch +--- + +Read docblock in nested flow object types and use them as descriptions diff --git a/packages/react-docgen/src/utils/__tests__/__snapshots__/getFlowType-test.ts.snap b/packages/react-docgen/src/utils/__tests__/__snapshots__/getFlowType-test.ts.snap index 10e0c8280e3..b06529f787c 100644 --- a/packages/react-docgen/src/utils/__tests__/__snapshots__/getFlowType-test.ts.snap +++ b/packages/react-docgen/src/utils/__tests__/__snapshots__/getFlowType-test.ts.snap @@ -1,5 +1,65 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html +exports[`getFlowType > detects object types with descriptions 1`] = ` +{ + "name": "signature", + "raw": "{ + /** A */ + a: string, + /** B */ + b?: xyz +}", + "signature": { + "properties": [ + { + "description": "A", + "key": "a", + "value": { + "name": "string", + "required": true, + }, + }, + { + "description": "B", + "key": "b", + "value": { + "name": "xyz", + "required": false, + }, + }, + ], + }, + "type": "object", +} +`; + +exports[`getFlowType > detects object types with maybe type 1`] = ` +{ + "name": "signature", + "raw": "{ a: string, b: ?xyz }", + "signature": { + "properties": [ + { + "key": "a", + "value": { + "name": "string", + "required": true, + }, + }, + { + "key": "b", + "value": { + "name": "xyz", + "nullable": true, + "required": true, + }, + }, + ], + }, + "type": "object", +} +`; + exports[`getFlowType > handles ObjectTypeSpreadProperty 1`] = ` { "name": "signature", diff --git a/packages/react-docgen/src/utils/__tests__/getFlowType-test.ts b/packages/react-docgen/src/utils/__tests__/getFlowType-test.ts index 435ce19fe18..89b421f578a 100644 --- a/packages/react-docgen/src/utils/__tests__/getFlowType-test.ts +++ b/packages/react-docgen/src/utils/__tests__/getFlowType-test.ts @@ -433,23 +433,29 @@ describe('getFlowType', () => { }); }); + test('detects object types with descriptions', () => { + const typePath = parse + .expression( + `x: { + /** A */ + a: string, + /** B */ + b?: xyz + }`, + ) + .get('typeAnnotation') + .get('typeAnnotation'); + + expect(getFlowType(typePath)).toMatchSnapshot(); + }); + test('detects object types with maybe type', () => { const typePath = parse .expression('x: { a: string, b: ?xyz }') .get('typeAnnotation') .get('typeAnnotation'); - expect(getFlowType(typePath)).toEqual({ - name: 'signature', - type: 'object', - signature: { - properties: [ - { key: 'a', value: { name: 'string', required: true } }, - { key: 'b', value: { name: 'xyz', nullable: true, required: true } }, - ], - }, - raw: '{ a: string, b: ?xyz }', - }); + expect(getFlowType(typePath)).toMatchSnapshot(); }); test('resolves imported types used for objects', () => { diff --git a/packages/react-docgen/src/utils/getFlowType.ts b/packages/react-docgen/src/utils/getFlowType.ts index 96b76662e90..8a7335d51c1 100644 --- a/packages/react-docgen/src/utils/getFlowType.ts +++ b/packages/react-docgen/src/utils/getFlowType.ts @@ -32,6 +32,7 @@ import type { TypeParameterDeclaration, UnionTypeAnnotation, } from '@babel/types'; +import { getDocblock } from './docblock.js'; const flowTypes: Record = { AnyTypeAnnotation: 'any', @@ -239,20 +240,34 @@ function handleObjectTypeAnnotation( if (Array.isArray(indexers)) { indexers.forEach((param) => { - type.signature.properties.push({ + const typeDescriptor: (typeof type.signature.properties)[number] = { key: getFlowTypeWithResolvedTypes(param.get('key'), typeParams), value: getFlowTypeWithRequirements(param.get('value'), typeParams), - }); + }; + const docblock = getDocblock(param); + + if (docblock) { + typeDescriptor.description = docblock; + } + + type.signature.properties.push(typeDescriptor); }); } path.get('properties').forEach((param) => { if (param.isObjectTypeProperty()) { - type.signature.properties.push({ + const typeDescriptor: (typeof type.signature.properties)[number] = { // For ObjectTypeProperties `getPropertyName` always returns string key: getPropertyName(param) as string, value: getFlowTypeWithRequirements(param.get('value'), typeParams), - }); + }; + const docblock = getDocblock(param); + + if (docblock) { + typeDescriptor.description = docblock; + } + + type.signature.properties.push(typeDescriptor); } else if (param.isObjectTypeSpreadProperty()) { let spreadObject = resolveToValue(param.get('argument'));