使用children作为Storybook的arg时出现TypeScript类型错误
解决Storybook中复用Story作为children时的TypeScript类型错误
问题原因
Storybook的ComponentStory默认会将组件props推断为可选类型(支持通过argTypes补全缺失参数),但你定义的Primary.args其实是完整的必填参数,TypeScript无法自动识别这一事实,导致传递给Button组件时出现类型不匹配。
解决方案
1. 用非空断言明确args的确定性
直接给Primary.args加上非空断言,告知TypeScript这些参数不会是undefined:
PrimaryButtonGroup.args = { children: ( <> <Primary {...Primary.args!} /> <Primary {...Primary.args!} /> </> ), }
2. 抽离类型安全的固定args常量(推荐)
在Button.stories.tsx中将Primary的参数抽成一个常量,让TypeScript准确推断其字面量类型:
// Button.stories.tsx import { ComponentStory, ComponentMeta } from "@storybook/react" import { Button } from "./Button" export default { title: "Example/Button", component: Button, argTypes: { backgroundColor: { control: "color" }, }, } as ComponentMeta<typeof Button> // 抽离类型安全的参数常量 export const primaryButtonArgs = { primary: true, label: "Button", } as const const Template: ComponentStory<typeof Button> = (args) => <Button {...args} /> export const Primary = Template.bind({}) Primary.args = primaryButtonArgs
然后在ButtonGroup.stories.tsx中导入该常量使用:
import { ComponentStory, ComponentMeta } from "@storybook/react" import { ButtonGroup } from "./ButtonGroup" import { Primary, primaryButtonArgs } from "../Button/Button.stories" export default { title: "Example/ButtonGroup", component: ButtonGroup, argTypes: {}, } const Template: ComponentStory<typeof ButtonGroup> = (args) => <ButtonGroup {...args} /> export const PrimaryButtonGroup = Template.bind({}) PrimaryButtonGroup.args = { children: ( <> <Primary {...primaryButtonArgs} /> <Primary {...primaryButtonArgs} /> </> ), }
3. 直接渲染Button组件而非Story模板
既然ButtonGroup需要的是Button实例,直接使用Button组件并传入参数,绕开Story模板的类型限制:
import { ComponentStory, ComponentMeta } from "@storybook/react" import { ButtonGroup } from "./ButtonGroup" import { Button } from "../Button/Button" import { primaryButtonArgs } from "../Button/Button.stories" export default { title: "Example/ButtonGroup", component: ButtonGroup, argTypes: {}, } const Template: ComponentStory<typeof ButtonGroup> = (args) => <ButtonGroup {...args} /> export const PrimaryButtonGroup = Template.bind({}) PrimaryButtonGroup.args = { children: ( <> <Button {...primaryButtonArgs} /> <Button {...primaryButtonArgs} /> </> ), }
内容的提问来源于stack exchange,提问作者Moon
相关产品推荐
相关产品推荐

