Storybook: Storybook 6.0 not picking up types from interfaces

Created on 23 Sep 2020  路  8Comments  路  Source: storybookjs/storybook

Describe the bug
I'm trying out storybook with an inner-source typescript react library I maintain at work (unfortunately, it is not public, but I think I can provide some anonymized examples).

Funtionally, storybook is working great, but it doesn't pick up the types for documentation. My "Docs" tab is the same thing the user who filed #12212 is seeing, just a recapitulation of the "Canvas" tab.

Screenshots
Screen Shot 2020-09-23 at 5 00 09 PM

Screen Shot 2020-09-23 at 5 00 19 PM

Code snippets
my .storybook/main.js:

module.exports = {
  "stories": [
    "../src/**/*.stories.mdx",
    "../src/**/*.stories.@(js|jsx|ts|tsx)"
  ],
  "addons": [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/preset-create-react-app"
  ],
  "typescript": {
    check: false,
    checkOptions: {},
    reactDocgen: 'react-docgen-typescript',
    reactDocgenTypescriptOptions: {
      shouldExtractLiteralValuesFromEnum: true,
      propFilter: (prop) => (prop.parent ? !/node_modules/.test(prop.parent.fileName) : true),
    },
  },
}

my Button.stories.tsx:

import React from 'react';
import { Story, Meta } from '@storybook/react';

import { Button, ButtonProps } from 'myLibraryNameHere';

export default {
  title: 'Example/Button',
  component: Button,
  argTypes: {
    variant: {
      control: {
        type: 'select',
        options: ['destructive', 'outline', 'primary', 'standard', 'workflowAction']
      }
    },
    compact: {
      control: 'boolean',
    }
  },
  args: {
    children: 'Button',
    variant: 'standard',
  },
} as Meta;

const Template: Story<ButtonProps> = (args) => <Button {...args} />;

export const Primary = Template.bind({});
Primary.args = {
  variant: 'primary',
};

export const Standard = Template.bind({});
Standard.args = {
};

export const Compact = Template.bind({});
Compact.args = {
  compact: true,
};

And here's what the Button.tsx file in my library looks like (well, a very simplified view of its structure anyway):

import MuiButton from '@material-ui/core/Button'
import React, {forwardRef} from 'react'

import withTheme from '../hoc/withTheme'

import {ButtonProps} from './Button.model'
import style from './Button.style'

export const Button = forwardRef<HTMLElement, ButtonProps>(({...props}: ButtonProps, ref: React.Ref<HTMLElement>) => (
  <MuiButton {...props}/>
))

/**
 * JSDOC COMMENT
 */
const MyCompanyButton = withTheme(Button, style)

MyCompanyButton.displayName = 'Button'

MyCompanyButton.defaultProps = {
  component: 'button',
  variant: 'standard',
}

export default MyCompanyButton

System:

Environment Info:

System:
OS: macOS 10.15.6
CPU: (4) x64 Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz
Binaries:
Node: 14.11.0 - /usr/local/bin/node
Yarn: 1.22.5 - /usr/local/bin/yarn
npm: 6.14.8 - /usr/local/bin/npm
Browsers:
Chrome: 85.0.4183.121
Firefox: 79.0
Safari: 14.0
npmPackages:
@storybook/addon-actions: ^6.0.21 => 6.0.21
@storybook/addon-essentials: ^6.0.21 => 6.0.21
@storybook/addon-links: ^6.0.21 => 6.0.21
@storybook/node-logger: ^6.0.21 => 6.0.21
@storybook/preset-create-react-app: ^3.1.4 => 3.1.4
@storybook/react: ^6.0.21 => 6.0.21

Additional context
We're forwarding refs because otherwise they can't be passed properly to the MUI component. Is that what's causing the issue here? or maybe the withTheme HOC?

We use react-docgen-typescript to generate type documentation without an issue, so I don't think this is an issue with docgen... any insight from you all would be appreciated. If I could fix this, I think I'd just move all my docs to a Storybook!

docs argstable question / support

All 8 comments

Additional note: the docs for default starter stories (header and page) that come with a new instance of storybook _are_ working just fine

I think this is the issue:

import { Button, ButtonProps } from 'myLibraryNameHere';

Does it work if you replace it with:

import { Button, ButtonProps } from '../../path/to/myLibrary';

Storybook doesn't currently extract types from node_modules https://github.com/storybookjs/storybook/issues/12185

oh @shilman ok, this must be it. I was trying to do this in a different project from where my library code is!

Thank you for the reply, I'll close this issue since it's a known issue/expected current behavior.

oops! Hey @shilman I'm back.

I've set up storybook in my lib repo, and it looks like the same problem occurs when I import from ../path/to/myLibrary. None of the types are picked up.

I have this in the story file:

// Button.stories.tsx

import React from 'react';
import { Story, Meta } from '@storybook/react/types-6-0';

import { Button, ButtonProps } from '../components';

export default {
  title: 'Example/Button',
  component: Button,
  args: {
    children: "Button",
  }
} as Meta;

const Template: Story<ButtonProps> = (args) => <Button {...args} />;

export const Primary = Template.bind({});
Primary.args = {
  variant: 'primary'
};

export const Standard = Template.bind({});
Standard.args = {
};

export const Compact = Template.bind({});
Compact.args = {
  compact: true,
};

Button and ButtonProps are named exports in ./src/components/index.ts.

However, it _does_ work if I separately import the component from the file where it's defined and use _that_ for the component prop:

// Button.stories.tsx with separate import for component def

import React from 'react';
import { Story, Meta } from '@storybook/react/types-6-0';

import { Button, ButtonProps } from '../components';

import { Button as B } from '../components/Button/Button'

export default {
  title: 'Example/Button',
  component: B,
  args: {
    children: "Button",
  }
} as Meta;

const Template: Story<ButtonProps> = (args) => <Button {...args} />;

export const Primary = Template.bind({});
Primary.args = {
  variant: 'primary'
};

export const Standard = Template.bind({});
Standard.args = {
};

export const Compact = Template.bind({});
Compact.args = {
  compact: true,
};

inside ./src/components/Button/Button.tsx I export an unstyled component as a named export, then default export a component styled with a withTheme HOC. Roughly like this:


/** this is "B" in the Buttons.stories.tsx file. It's really just the
 * functional base, no styling is applied to it yet.
 */
export const Button = forwardRef<HTMLElement, ButtonProps>(
  (props: ButonProps, ref: Ref<HTMLElement>) => { ... }
)
const ThemedButton = withTheme(Button, style)

/** This is used as the named export "Button" in src/components/index.ts.
 * This is the actual Button component exposed in our library.
 */
export default ThemedButton

Could it be the HOC that's throwing this off? The re-exporting a default export as a named export?

Yeah that sounds right. What happens if you set the default.component to be the inner Button instead of the HOC-wrapped one?

@shilman yep, that's what I'm doing with import { Button as B } ... in the stories.tsx file code above. The problem is that I don't want to export that, it should never be used in my library since it does not have styling applied.

the withTheme/withStyle stuff I'm using is out of Material UI. Have you all run into anyone else with similar issues with HOCs blocking react-docgen-typescript from picking up types? I took a look through their issue tracker and it looks like they (supposedly) do support reading the types from the return of an HOC.

I have the same issue.
if I change the types' export code to "export * from '.........'", there are no error. But I wouldn't like to export all. I need to export like "export {xxxxx, yyyyyyy} from '.......'".

Was this page helpful?
0 / 5 - 0 ratings

Related issues

miljan-aleksic picture miljan-aleksic  路  3Comments

tlrobinson picture tlrobinson  路  3Comments

Jonovono picture Jonovono  路  3Comments

rpersaud picture rpersaud  路  3Comments

shilman picture shilman  路  3Comments