基于其他Prop值实现TypeScript条件式组件Props
实现基于actions数组的TypeScript精准Props提示
问题背景
现有一个用于组件Props的FilterActionsProps接口,支持通过actions字符串数组指定要显示的操作(如['export', 'reset', 'submit']),但TypeScript智能提示无法根据actions的内容自动过滤仅显示对应的回调Props,需要增强类型关联,让提示精准匹配actions中指定的操作。
当前接口代码:
interface FilterActionsProps { onExport?: () => Promise<void>; onReset?: () => void; onSubmit?: () => void; actions?: ('export' | 'reset' | 'submit')[]; }
期望效果:
- 当
actions仅包含'submit'时,仅提示onSubmitProp; - 当
actions包含'submit'和'reset'时,提示onSubmit和onResetProp; - 当
actions包含'submit'和'export'时,提示onSubmit和onExportProp; - 当
actions包含全部三个值时,提示所有三个回调Prop。
解决方案
通过泛型+类型映射实现actions与回调Props的强关联,让TypeScript根据actions的具体元素自动推导可使用的回调:
// 定义所有支持的操作类型 type Action = 'export' | 'reset' | 'submit'; // 建立操作与对应回调的映射关系 type ActionCallbacks = { export: () => Promise<void>; reset: () => void; submit: () => void; }; // 泛型Props类型:根据传入的actions数组元素,自动筛选对应的回调 type FilterActionsProps<T extends Action[]> = { actions: readonly T; } & { [K in keyof ActionCallbacks as `on${Capitalize<K>}`]?: T[number] extends K ? ActionCallbacks[K] : never; }; // 组件定义示例 const Component = <T extends Action[]>(props: FilterActionsProps<T>) => { return null; // 组件实现逻辑 };
验证示例
以下示例中,TypeScript将仅提示与actions匹配的回调Props:
// 仅提示onSubmit <Component actions={['submit']} onSubmit={() => {}} /> // 提示onSubmit和onReset <Component actions={['submit', 'reset']} onReset={() => {}} /> // 提示onSubmit和onExport <Component actions={['submit', 'export']} onSubmit={() => {}} onExport={() => Promise.resolve()} /> // 提示全部三个回调 <Component actions={['submit', 'reset', 'export']} onSubmit={() => {}} onReset={() => {}} onExport={() => Promise.resolve()} />
原理说明
- 用泛型
T捕获actions数组的具体元素类型,通过readonly T让TypeScript保留数组的字面量类型信息; - 通过
keyof ActionCallbacks遍历所有操作,利用Capitalize将操作名转换为回调Prop的前缀(如export→onExport); - 条件判断
T[number] extends K:仅当当前操作K存在于actions数组元素中时,才允许对应的回调Prop,否则设为never(TypeScript会自动隐藏never类型的属性)。
内容的提问来源于stack exchange,提问作者Ali Ehyaie
相关产品推荐
相关产品推荐

