如何在Storybook中仅为Story Controls扩展Modal组件接口?
解决Storybook中给无isOpen属性的Modal添加Controls面板控制的TypeScript问题
核心问题是你的Modal组件本身不接收isOpen属性,直接扩展组件Props类型会触发TypeScript的类型检查错误。正确的做法是利用Storybook的argTypes添加自定义控制参数,在Story的渲染逻辑中使用该参数控制Modal的显示/隐藏,而非传递给组件本身。
具体实现步骤
在Story的meta中声明自定义
isOpen控制属性
通过argTypes字段定义isOpen为布尔型控制项,指定默认值和描述,让Storybook识别这个自定义参数。在Story的render函数中分离参数
从args中解构出isOpen,将剩余的参数传递给Modal组件,同时用isOpen控制AnimatePresence内的Modal渲染。
完整代码示例
import type { Meta, StoryObj } from '@storybook/react'; import { AnimatePresence } from 'framer-motion'; import Modal from './Modal'; // 定义Story元数据 const meta: Meta<typeof Modal> = { component: Modal, argTypes: { isOpen: { control: 'boolean', defaultValue: true, description: '控制Modal的显示与隐藏', }, }, }; export default meta; type Story = StoryObj<typeof Modal>; // 默认Story示例 export const Default: Story = { args: { title: '示例弹窗', content: '这是弹窗的测试内容', isOpen: true, }, render: (args) => { // 分离自定义的isOpen和Modal本身需要的props const { isOpen, ...modalProps } = args; return ( <AnimatePresence> {isOpen && <Modal {...modalProps} />} </AnimatePresence> ); }, };
为什么之前的方法失败?
你之前尝试将类型扩展为typeof Modal & { isOpen: boolean },但Modal组件的Props中并不包含isOpen,TypeScript会严格检查传递给组件的属性是否合法。而通过argTypes添加的自定义参数属于Storybook的控制参数,并非组件本身的Props,因此不会触发类型冲突。
内容的提问来源于stack exchange,提问作者Jason McFarlane
相关产品推荐
相关产品推荐

