如何为含辨别联合类型Props的Button组件编写Storybook测试
问题背景
技术栈:Nextjs 13.4.10、Storybook 7.1.1、TypeScript 5.1.6
Button组件的Props采用辨别联合类型定义:
type ButtonRect = { shape?: "rect"; text: string; isLoading?: boolean; icon?: ButtonIconName | ReactElement; iconPosition?: "left" | "right" | "both"; }; type ButtonCircle = { shape: "circle"; icon: ButtonIconName | ReactElement; }; type ButtonCommon = { type?: "button" | "submit"; onClick?: () => void; color: ButtonColor; disabled?: boolean; title?: string; display?: Display; backgroundType?: BackgroundType; }; type Props = (ButtonRect | ButtonCircle) & ButtonCommon; export function Button(props: Props) {...}
编写Storybook测试时,args属性触发TypeScript错误,原因是联合类型的互斥属性导致无法同时满足所有分支的类型要求。
解决方案
针对联合类型的每个分支分别编写独立的Story,确保每个Story的args严格匹配对应分支的类型,既解决TypeScript类型错误,又覆盖组件的所有使用场景。
完整测试代码
import type { Meta, StoryObj } from "@storybook/react"; import { Button } from "./Button"; const meta: Meta<typeof Button> = { title: "inputs/Button", component: Button, } satisfies Meta<typeof Button>; export default meta; type Story = StoryObj<typeof meta>; // 矩形按钮测试用例 export const RectPrimary: Story = { args: { color: "primary", type: "button", disabled: false, title: "click for ...", onClick: () => console.log("clicked!"), display: "auto", backgroundType: "filled", shape: "rect", text: "CLICCAMI", isLoading: false, icon: "product", iconPosition: "left", }, }; // 圆形按钮测试用例 export const CirclePrimary: Story = { args: { color: "primary", type: "button", disabled: false, title: "circle button", onClick: () => console.log("circle clicked!"), display: "auto", backgroundType: "filled", shape: "circle", icon: "product", }, };
说明
- 每个Story的
args严格对应联合类型的一个分支:矩形按钮包含text、可选isLoading等属性;圆形按钮必须有shape: "circle"和icon,且不包含text属性。 - TypeScript会自动验证每个Story的
args是否符合对应分支的类型,避免错误。 - 通过拆分Story,可以清晰展示组件的不同形态和配置选项。
内容的提问来源于stack exchange,提问作者Daniele
相关产品推荐
相关产品推荐

