diff --git a/.changeset/complete-indexed-type-details.md b/.changeset/complete-indexed-type-details.md new file mode 100644 index 00000000000..67d56c96d75 --- /dev/null +++ b/.changeset/complete-indexed-type-details.md @@ -0,0 +1,5 @@ +--- +'react-docgen': patch +--- + +Preserve union members and nested type details when resolving TypeScript indexed access properties. diff --git a/packages/react-docgen/src/utils/__tests__/getTSType-test.ts b/packages/react-docgen/src/utils/__tests__/getTSType-test.ts index 0413d2b8503..962de769b9c 100644 --- a/packages/react-docgen/src/utils/__tests__/getTSType-test.ts +++ b/packages/react-docgen/src/utils/__tests__/getTSType-test.ts @@ -426,6 +426,36 @@ describe('getTSType', () => { expect(getTSType(typePath)).toMatchSnapshot(); }); + test('preserves union members in indexed access', () => { + const typePath = typeAlias(` + var x: Base["size"]; + type Base = { size: "small" | "large" }; + `); + + expect(getTSType(typePath)).toMatchObject({ + name: 'union', + raw: 'Base["size"]', + elements: [ + { name: 'literal', value: '"small"' }, + { name: 'literal', value: '"large"' }, + ], + }); + }); + + test('preserves object signatures in indexed access', () => { + const typePath = typeAlias(` + var x: Base["options"]; + type Base = { options: { enabled: boolean } }; + `); + + expect(getTSType(typePath)).toMatchObject({ + name: 'signature', + signature: { + properties: [{ key: 'enabled', value: { name: 'boolean' } }], + }, + }); + }); + test('resolves indexed access of array', () => { const typePath = parseTypescript .statement( diff --git a/packages/react-docgen/src/utils/getTSType.ts b/packages/react-docgen/src/utils/getTSType.ts index 91346f11915..1fdd5e531ec 100644 --- a/packages/react-docgen/src/utils/getTSType.ts +++ b/packages/react-docgen/src/utils/getTSType.ts @@ -482,8 +482,16 @@ function handleTSIndexedAccessType( return { name: 'unknown' }; } + const valueType: TypeDescriptor & { + required?: boolean; + } = { + ...resolvedType.value, + }; + + delete valueType.required; + return { - name: resolvedType.value.name, + ...valueType, raw: printValue(path), }; }