如何在Storybook的select选项中使用TypeScript定义的Props联合类型值
问题原因
你当前的写法无法生效的核心原因是:TypeScript的interface属于编译期类型定义,会在编译为JS的过程中被完全抹除,不存在于运行时环境。你代码里的Props是类型而非普通JS对象,自然无法在运行时读取Props.type的属性值。
可行解决方案
方案1:类型和运行时常量同源(最推荐)
先定义运行时可用的常量数组,再基于数组反向推导TypeScript类型,保证类型定义和可选值完全同步,无需重复维护两份列表:
// typings.ts 调整写法 // 先定义常量数组,用as const锁定值类型 export const ANIMAL_TYPE_OPTIONS = ['dog', 'cat', 'mouse', 'turtle', 'rabbit'] as const; // 基于数组推导联合类型 export type AnimalType = typeof ANIMAL_TYPE_OPTIONS[number]; // 定义Props接口 export interface Props { type: AnimalType } export default Props;
之后在Storybook配置中直接引用这个常量数组即可:
import React from 'react'; import Props, { ANIMAL_TYPE_OPTIONS } from '../typings'; import Animal from './Animal'; export default { title: 'Animals', component: Animal, argTypes: { type: { control: { type: 'select', options: ANIMAL_TYPE_OPTIONS, }, }, }, };
后续新增可选值只需修改ANIMAL_TYPE_OPTIONS数组,类型和Storybook下拉选项会自动同步,维护成本极低。
方案2:依赖Storybook自动类型识别(Storybook 6.5+支持)
如果你的项目已经开启了Storybook的TypeScript类型自动解析功能,不需要手动配置argTypes的options,Storybook会自动识别Props中type字段的联合类型,自动生成对应下拉选项,你只需要保证Storybook的主配置中开启了类型检测即可,无需额外修改代码。
其他备选方案
如果不想调整原有类型定义,也可以引入ts-transformer-enumerate这类TypeScript编译插件,在编译阶段把联合类型转换为运行时可用的数组,但需要修改项目的编译配置,整体成本远高于方案1,非特殊场景不推荐使用。
内容的提问来源于stack exchange,提问作者Alyona
相关产品推荐
相关产品推荐

