CSF3中如何正确使用TypeScript完成Story类型标注
CSF3 规范 Storybook TypeScript 类型标注落地指南
报错根因说明
你遇到的两类报错都属于类型误用,和Storybook本身无关:
- NoFiltering的函数签名报错是核心问题:
ComponentStory是CSF2(旧版函数式故事)专用类型,本质是函数类型,要求值必须是(args: Props, context: StoryContext) => 组件返回值的格式,和CSF3的对象式故事结构完全不兼容,才会出现「对象不匹配函数签名」的提示。 - Default的args类型报错,是因为你写
as Meta时没有传入组件泛型,TS无法关联组件的Props类型,自然无法对args做正确的类型校验。
正确实现步骤
- 导入正确类型
CSF3规范下完全不需要使用旧版ComponentMeta、ComponentStory类型,直接从你使用的框架对应的Storybook包中导入Meta和StoryObj即可,React项目示例:
import type { Meta, StoryObj } from '@storybook/react'; // Vue3项目替换为 @storybook/vue3,其他框架对应替换包名即可 import { DataPresentation } from './DataPresentation'; import DataTableStories from '../DataTable/DataTable.stories';
- 正确标注默认导出的Meta类型
不要使用无泛型的as Meta,优先用TS 4.9+支持的satisfies做类型校验,既可以保证Meta配置符合类型要求,又不会丢失类型推导:
export default { component: DataPresentation, } satisfies Meta<typeof DataPresentation>;
如果你的TS版本低于4.9不支持
satisfies,可以替换为as Meta<typeof DataPresentation>,不影响核心功能。
- 正确标注故事对象类型
所有CSF3对象式故事,统一使用StoryObj<typeof 组件>作为类型,替换原来的ComponentStory:
const Default: StoryObj<typeof DataPresentation> = { args: { ...DataTableStories.Default.args, tableId: "players" }, }; const NoFiltering: StoryObj<typeof DataPresentation> = { storyName: 'No search/filter args', ...Default, }; export { Default, NoFiltering };
额外注意事项
- 如果展开其他故事的args时仍有类型报错,先检查被引用的故事(比如示例中的
DataTableStories.Default)是否也用了正确的StoryObj类型标注。如果旧故事用了ComponentStory类型,其args的类型推导会失效,替换为StoryObj即可解决。 - 不要混用CSF2和CSF3类型:只有写自定义render函数、或者维护老版本函数式故事的时候,才需要用
StoryFn类型(即原ComponentStory的新版别名),纯对象格式的故事一律用StoryObj。 - 你之前找不到对应文档,是因为Storybook 7.0正式将CSF3作为默认规范后,旧版CSF2的类型文档被归档到历史版本目录,当前版本官方文档的所有示例均采用
Meta+StoryObj的类型组合。
内容的提问来源于stack exchange,提问作者Jonathan Tuzman
相关产品推荐
相关产品推荐

