I'm not sure if this also the case stories written in CSF.
I've noticed a couple of limitations when trying to auto generating prop tables in typescript.
1. It looks like only Interfaces are supported, using a Type seems to break it.
2. using generics (in the case of react) seem to break it too, example below:
This works:
export const Text = ({
padding = '0',
margin,
}: Props) => ()
This doesn't
export const Text: React.FC<Props> = ({
padding = '0',
margin,
}) => ()
3. Using imported types like the example below are always inferred as any
export interface Props {
foo: SomeImportedType['property']
}
4. Doesnt work with React.forwardRef
forwardRef is a dupe to #7933, will treat that separately. The rest are super interesting, and I hope to dig in soon.
I'm also not getting any details for my props. Im seeing the prop name, but not type or default, even though it is defined in the component. Im using CSF, but project is gatsby so using manual install with webapck config, not the preset. Very open for it being my own config causing this, Im no webpack pro. Components are functional so no React.Component options like described above.
Was struggling with other issues, they should be fixed now, heres a repo: https://github.com/netliferesearch/netlife2019/tree/storybook_setup_stories
FYI, @mrmckeb has done some awesome detective work that's possibly related to this. The TLDR is that there may be two problems:
tsconfig.json using something like this: tsDocgenLoaderOptions: {
tsconfigPath: path.resolve(__dirname, '../tsconfig.json'),
},
// The Babel plugin for docgen conflicts with the TypeScript loader.
// This limits it to JavaScript files when the TypeScript loader is enabled.
if (options.tsDocgenLoaderOptions) {
plugins = _plugins.filter(
([plugin]) => !plugin.includes('babel-plugin-react-docgen')
);
overrides = [
{
test: /\.(js|jsx)$/,
plugins: _plugins.filter(([plugin]) =>
plugin.includes('babel-plugin-react-docgen')
),
},
];
These changes have improved the docgen support in the CRA preset's typescript docgen settings: https://github.com/storybookjs/presets/pull/44/files
I'm not sure how to operationalize them for more general configuration yet, but wanted to record that here in case anybody wants to experiment in their own setups!
@shilman I'm not using typescript and still not seeing prop types and defaults. Should I file a separate bug?
@kfayelun Yeah, I think that's a separate issue (though it may end up being the same underlying problem). Thanks!
We do know that the TS and JS loaders/plugins can interfere with each other. A good base test is to ensure that you don't have both in the mix ;)
Insight for point 1, 2, and 4: For us, it turned out that this is caused by how we extend Component: If we do class MyComponent extends React.Component, descriptions are omitted. If we use a named import of Component instead (class MyComponent extends Component), descriptions work! This also applies to React.FC vs FC!
We were even able to use type like this:
type CheckboxProps = {
id: string;
}
const Checkbox: FC<CheckboxProps> = props => {
...
}
🤔 The error with React.forwardRef might also be solvable with named imports but we don't use it here and I'm not sure how to use it.
@jonathanherdt ❤️ ❤️ ❤️ Thanks for tracking this down. Super helpful!
Re: forwardRef, there's a PR in progress https://github.com/storybookjs/storybook/pull/8445
Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks!
Generics issue (2) repro: https://github.com/storybookjs/storybook/commit/e3927d9cea7dc7fe2473eff06e2223e150ff2755
I believe this is the corresponding react-docgen issue: https://github.com/reactjs/react-docgen/issues/387
Type import issue (3) repro: https://github.com/storybookjs/storybook/commit/412977380dbbe30f72f084d51f637ddcfbe1a96a
Possibly fixed in https://github.com/reactjs/react-docgen/pull/352
We've just released zero-config typescript support in 6.0-beta. Please upgrade and test it!
Thanks for your help and support getting this stable for release!
Possibly fixed, but ArgsTable is not rendered

// icon.tsx
import React, {ComponentProps} from 'react';
import AntdIcon from '@ant-design/icons/lib/components/Icon';
type Props = ComponentProps<typeof AntdIcon>;
const Icon = React.forwardRef<HTMLSpanElement, Props>(({...props}, ref) => {
return <AntdIcon data-test={AntdIcon.displayName} ref={ref} {...props} />;
});
export {Icon};
export type {Props as IconProps};
// icon.story.tsx
import React from 'react';
import {Story} from '@storybook/react/types-6-0';
import {MessageOutlined} from '@ant-design/icons';
import {Icon, IconProps} from '../..';
const IconDefaultTemplate: Story<IconProps> = ({...props}) => {
return <Icon component={MessageOutlined} />;
};
const IconDefaultStory = IconDefaultTemplate.bind({});
IconDefaultStory.storyName = 'Базовый тип';
export {IconDefaultStory};
// icon.stories.mdx
import {Meta, ArgsTable, Story} from '@storybook/addon-docs/blocks';
import {Icon} from './icon';
import {IconDefaultStory} from './icon.story';
<Meta title={title} component={Icon} />
<Story name="Базовая иконка">
{IconDefaultStory}
</Story>
<ArgsTable of={Icon} />
This seems to be due to a limitation of Storybook that by default it only runs type extraction on the user's project. So I think what's happening is:
const Icon = React.forwardRef<HTMLSpanElement, Props>(({...props}, ref) => {
return <AntdIcon data-test={AntdIcon.displayName} ref={ref} {...props} />;
});
The argType extractor sees this code and tries to find the types for AntdIcon, but because that's defined in an external package, it's not available.
As a workaround, you can try setting the following option in .storybook/main.js:
module.exports = {
typescript: {
reactDocgenTypescriptOptions: {
shouldExtractLiteralValuesFromEnum: true,
shouldRemoveUndefinedFromOptional: true,
},
},
};
This removes the default propFilter which is:
propFilter: (prop: any) => (prop.parent ? !/node_modules/.test(prop.parent.fileName) : true),
More info: https://storybook.js.org/docs/react/configure/typescript
This probably needs documentation @jonniebigodes
@shilman, that works, although argTypes is not an optional parameter now. Thanks!
Additionally I'd to pay attention to the main problem I asked before:
import React from 'react';
import {Story} from '@storybook/react/types-6-0';
import AntButton from 'antd/lib/button';
export const argTypes = {
href: {
description: 'Ссылка, куда будет выполняться перенаправление',
table: {
type: {
summary: 'string'
}
},
control: {
type: 'text'
}
}
};
export const ButtonDefaultTemplate = ({...props}) => {
return <Button {...props}>Кнопка</Button>;
};
export const ButtonDefaultStory = ButtonDefaultTemplate.bind({});
ButtonDefaultStory.storyName = 'Базовый тип';
<Meta title="Button" component={Button} argTypes={argTypes} />
<Preview>
<Story name="Button">
{ButtonDefaultStory}
</Story>
</Preview>
<ArgsTable of={Button} />

How to hide all inherited properties and show controls instead?
As a workaround, it's possible to create a custom table (but without controls):
import React, {ComponentProps, FunctionComponent} from 'react';
import {Table, Typography} from 'antd';
type TableProps = {
name: string;
dataSource: ComponentProps<typeof Table>['dataSource'];
};
const render = (html: string): JSX.Element => {
return <div dangerouslySetInnerHTML={{__html: html}} />;
}
const CustomArgsTable: FunctionComponent<TableProps> = ({name, dataSource}): JSX.Element => (
<div>
<Typography.Title level={3}>{name}</Typography.Title>
<Table dataSource={dataSource}
columns={[
{
title: 'Property',
dataIndex: 'property',
key: 'property'
},
{
title: 'Description',
dataIndex: 'description',
key: 'description',
render
},
{
title: 'Type',
dataIndex: 'type',
key: 'type',
render
},
{
title: 'Value',
dataIndex: 'value',
key: 'value'
}
]}
bordered={true}
pagination={{hideOnSinglePage: true}}
/>
</div>
);
export {CustomArgsTable};
import React from 'react';
import {Story} from '@storybook/react/types-6-0';
import {Button} from './button';
import {ButtonDefaultStory , argTypes} from './button.stories.tsx';
import {CustomArgsTable} from './utils.tsx';
export const dataSource = [
{
key: '1',
property: 'dropdownProps',
description: 'Props',
type: 'Dropdown',
value: '-'
},
<Meta title="Button" component={Button} argTypes={argTypes} />
<Preview>
<Story name="Button">
{ButtonDefaultStory}
</Story>
</Preview>
<CustomArgsTable name="Button" dataSource={dataSource} />