📖

satisfiesでmetaの型を定義したstorybookのファイルでtsのエラーが起きる

2025/03/11に公開

はじめに

Next.jsでStorybookを使用し、satisfiesを利用してmetaの型定義を行った際に、以下のエラーが発生しました。

Expression produces a union type that is too complex to represent.

このエラーが発生した状況と、その解決方法について解説します。

エラーが出た時の状況

  • Next.jsのpage.tsxが106個を超えたあたりからエラーが発生。
    • 106個という数に特に意味はないと思われる。
    • ページを追加するとエラーが発生する。ページを削除するとエラーが起きない。
  • satisfiesを使用してstorybookのmetaを定義していた。
  • それ以前はmetaの型定義にsatisfiesを使用しても問題なし。

解決方法

まず、先に解決方法から言うと、satisfiesを使用せずにmetaに型注釈をすることで解決しました。
解決というかシンプルな方法に変えただけですが…。

storybookのコンポーネント定義

例えば、以下のようなButtonコンポーネントがあるとします。

type Props = {
  primary: boolean;
  label: string;
};

export function Button({ primary, label }: Props) {
  return <button data-type={primary}>{label}</button>;
}

metaを型注釈で定義する場合

import type { Meta } from '@storybook/react';
 
import { Button } from '.';

const meta: Meta<typeof Button> = {
  component: Button,
};
export default meta;
 
type Story = StoryObj<typeof Button>;

export const Example = {
  args: {
    primary: true,
    label: 'Button'
  },
} satisfies Story;

satisfiesを使用する場合

typescript4.9以上を使用している場合、satisfiesを使用することが可能です。
satisfiesを使用することで、必須のプロパティがない場合にも型エラーを出すことができます。
参考:https://storybook.js.org/docs/configure/integration/typescript#typescript-49-support

import type { Meta, StoryObj } from '@storybook/react';

import { Button } from '.';

const meta = {
  component: Button,
} satisfies Meta<typeof Button>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Example = {
  args: {
    primary: true,
    // label: 'Button', // ⭐️labelは必須になっているので、ここでエラーが出る。
  },
} satisfies Story;

しかし、今回のエラーはsatisfiesの使用時に発生しました。
Expression produces a union type that is too complex to represent.のエラーが出ている

satisfiesを使用することでargsの型が変わる

argsの型が変わる

型注釈の場合

args?: (Partial<{
  primary: boolean;
  label: string;
}> & {
  primary?: boolean;
  label?: string;
})

satisfiesの場合

args: Partial<{
   primary: boolean;
   label: string;
}> & {
   primary: boolean;
   label: string;
}

バージョン

{
  "dependencies": {
    "next": "^14.2.16",
  },
  "devDependencies": {
    "@storybook/addon-essentials": "^8.3.6",
    "@storybook/addon-interactions": "^8.3.6",
    "@storybook/addon-links": "^8.3.6",
    "@storybook/addon-onboarding": "^8.3.6",
    "@storybook/addon-styling-webpack": "^1.0.0",
    "@storybook/blocks": "^8.3.6",
    "@storybook/experimental-nextjs-vite": "^8.3.6",
    "@storybook/nextjs": "^8.3.6",
    "@storybook/react": "^8.3.6",
    "@storybook/test": "^8.3.6",
    "storybook": "^8.3.6",
    "typescript": "^5.6.3"
  }
}

試したこと

1. VSCodeのTypeScriptバージョンを変更

下記のエラーを検索すると、エラーの解決策として、エディタのTypeScriptバージョンを変更する方法が提案されていました。

Expression produces a union type that is too complex to represent.

参考:https://github.com/chakra-ui/chakra-ui/issues/3714#issuecomment-1357167913

しかし、これを試してもエラーは解消しませんでした。

2. コンポーネントのプロパティ数を減らす

エラーが発生するコンポーネントとそうでないコンポーネントがあったため、propsの数を減らしてみましたが、エラーは解消しませんでした。

3. page.tsxの数を減らす

page.tsxの数を減らすことでエラーが解消しました。
ただし、ページの数を減らすことは現実的ではないため、別の方法を検討する必要がありました。

4. satisfiesをやめる

エラーが発生していたStorybookコンポーネントの型定義をsatisfiesから型注釈に変更しました。

const meta: Meta<typeof Button> = {
  component: Button,
};

この対応でエラーは解消しました。

おわりに

Storybookでsatisfiesを使用した場合に、

Expression produces a union type that is too complex to represent.

というエラーが発生することがあります。

今回のケースでは、

  • page.tsxの数が増えるとエラーが発生した
  • satisfiesをやめて型注釈にするとエラーが解消した

という現象が起きました。

根本的な解決ではないものの、型注釈を使用することで回避できるため、一時的な対応として有効なので、参考にしてみてください。

chot Inc. tech blog

Discussion