Search code examples
reactjstypescriptstorybook

Storybook Controls with Typescript keyof


I'm building up some components for use with Storybook and hitting upon a small snag with Typescript inferred types.

For the sake of DRY code, I'd rather not have to define the options for a control within the story itsself, however it doesn't seem to be inferring the options correctly.

I have a Button component that has an 'option' prop. The available options are strings based on the values in a theme:

buttonTheme?: keyof Theme['palette']['button']

In VSCode this is showing correctly as a union of the string keys ("base" | "brand" | "default" | "ghost" | "ghostWhite" | "link"), however in storybook this is showing as a key type (string | number | symbol) and the control has Set object as the control type, rather than radio buttons, or a dropdown list:

StorybookControl

If I change the Prop type from keyof Theme['palette']['button'] to the list of keys, then this works fine, however that adds another place to update the values should more get added, as does adding them explicitly into the story.

I've tried adding the shouldExtractValuesFromUnion option to the reactDocgenTypescriptOptions, but that just gives radio button options of string | number | symbol which is not what I want and actually breaks functionality (it also messes with boolean values and changes them from a toggle switch to true | false radio buttons).

My typescript config in the storybook's main.ts file is:

typescript: {
    check: false,
    checkOptions: {},
    reactDocgen: 'react-docgen-typescript',
    reactDocgenTypescriptOptions: {
      compilerOptions: {
        allowSyntheticDefaultImports: true,
        esModuleInterop: true,
      },
      // shouldExtractValuesFromUnion: true,
      shouldExtractLiteralValuesFromEnum: true,
      shouldRemoveUndefinedFromOptional: true,
      propFilter: (prop) => (prop.parent ? !/node_modules/.test(prop.parent.fileName) : true),
    },
  },

Not sure whether there is a setting or something I'm missing, or whether I'll have to resign to the fact that I'll have to explicitly define the options in the story file. Any help would be appreciated.


Solution

  • So it seems that some settings get changed as soon as you add a custom typescript section to the config.

    I've removed the typescript entry in the config and everything is working again, but if I add it back in (even empty) it breaks. There must be some default settings somewhere that I can replicate and change one-by-one to see the culprit, but I couldn't find them when looking through the repo.

    If I need any of the settings in future, I may look into it further, but for now this worked for me getting enums back in the code. Putting this here in case anyone stumbles across this in future.