Repository: storybookjs/storybook
File: code/lib/cli-storybook/src/codemod/helpers/remove-unused-types.test.ts (TypeScript)

Code before:

import { loadCsf, printCsf } from 'storybook/internal/csf-tools';

import { dedent } from 'ts-dedent';

import { getDiff } from '../../../../../core/src/core-server/utils/save-story/getDiff';
import { removeUnusedTypes } from './remove-unused-types';

expect.addSnapshotSerializer({
  serialize: (val: any) => (typeof val === 'string' ? val : val.toString()),
  test: () => true,
});

const unescape = (str: string) => str.replace(/\r\n/g, '\n');

describe('removeUnusedTypes', () => {
  const getTransformed = (source: string) => {
    const csf = loadCsf(source, { makeTitle: () => 'FIXME' }).parse();
    removeUnusedTypes(csf._ast.program, csf._ast);
    return printCsf(csf).code;
  };

  it('should remove unused Storybook types', async () => {
    const source = dedent`
      import { Button } from './Button';
      import { StoryFn, StoryObj, ComponentStory, Meta, MetaObj, ComponentMeta } from '@storybook/react';

      // unused types that should be removed
      type UnusedAlias = Meta<typeof Button>;
      type UnusedAlias2 = StoryObj<typeof Button>;
      type UnusedAlias3 = ComponentStory<typeof Button>;
      type UnusedAlias4 = ComponentMeta<typeof Button>;
      type UnusedDeepType = {
        foo: {
          bar: {
            story: StoryObj<typeof Button>;
          }
        }
      };
      interface UnusedInterface extends Meta {}
      interface UnusedDeepInterface {
        baz: {
          qux: {
            meta: Meta<typeof Button>;
          }
        }
      };

      export default { component: Button };
    `;


Review comment (suggestion):
```suggestion
      import type { StoryFn, StoryObj, ComponentStory, Meta, MetaObj, ComponentMeta } from '@storybook/react';
```

Code after:

import { loadCsf, printCsf } from 'storybook/internal/csf-tools';

import { dedent } from 'ts-dedent';

import { getDiff } from '../../../../../core/src/core-server/utils/save-story/getDiff';
import { removeUnusedTypes } from './remove-unused-types';

expect.addSnapshotSerializer({
  serialize: (val: any) => (typeof val === 'string' ? val : val.toString()),
  test: () => true,
});

const unescape = (str: string) => str.replace(/\r\n/g, '\n');

describe('removeUnusedTypes', () => {
  const getTransformed = (source: string) => {
    const csf = loadCsf(source, { makeTitle: () => 'FIXME' }).parse();
    removeUnusedTypes(csf._ast.program, csf._ast);
    return printCsf(csf).code;
  };

  it('should remove unused Storybook types', async () => {
    const source = dedent`
      import { Button } from './Button';
      import { StoryFn, StoryObj } from '@storybook/react';
      import type { Meta, MetaObj } from '@storybook/react';
      import { type ComponentStory, type ComponentMeta } from '@storybook/react';

      // unused types that should be removed
      type UnusedAlias = Meta<typeof Button>;
      type UnusedAlias2 = StoryObj<typeof Button>;
      type UnusedAlias3 = ComponentStory<typeof Button>;
      type UnusedAlias4 = ComponentMeta<typeof Button>;
      type UnusedDeepType = {
        foo: {
          bar: {
            story: StoryObj<typeof Button>;
          }
        }
      };
      interface UnusedInterface extends Meta {}
      interface UnusedDeepInterface {
        baz: {
          qux: {
            meta: Meta<typeof Button>;
          }
        }
      };

      export default { component: Button };