React+TypeScript中带区分联合的泛型FilterConfig复用问题
解决React+TypeScript可配置Filter UI组件的泛型复用问题
核心思路是把泛型类型信息内嵌到联合类型的具体成员中,通过标识字段(如valueType)让TypeScript自动推断类型,避免每次使用都手动传入泛型参数。以下是具体实现步骤:
1. 定义基础Filter类型
先抽取出所有Filter组件通用的属性,减少重复代码:
// 通用基础配置,所有Filter都继承这个类型 type BaseFilterConfig = { key: string; // 唯一标识,用于提交筛选参数 label: string; // 筛选器显示标签 type: 'checkbox'; // 可扩展为input/select等其他筛选器类型 };
2. 按值类型拆分CheckboxFilter配置
针对数字、字符串、枚举三种值类型,分别定义对应的CheckboxFilter子类型,通过valueType字段做区分:
// 字符串类型的Checkbox筛选器 type StringCheckboxFilter = BaseFilterConfig & { valueType: 'string'; options: { label: string; value: string }[]; // 选项值为字符串 }; // 数字类型的Checkbox筛选器 type NumberCheckboxFilter = BaseFilterConfig & { valueType: 'number'; options: { label: string; value: number }[]; // 选项值为数字 }; // 枚举类型的Checkbox筛选器 type EnumCheckboxFilter<T extends string | number> = BaseFilterConfig & { valueType: 'enum'; options: { label: string; value: T }[]; // 选项值为指定枚举类型 };
3. 组合成无需泛型的FilterConfig联合类型
把上面的子类型组合成联合类型,这样使用时不需要手动传入泛型参数:
// 示例枚举(根据业务需求自定义) enum OrderStatus { Pending = 'PENDING', Shipped = 'SHIPPED', Delivered = 'DELIVERED' } // 最终的FilterConfig联合类型,支持所有值类型的Checkbox筛选器 type FilterConfig = | StringCheckboxFilter | NumberCheckboxFilter | EnumCheckboxFilter<OrderStatus>;
4. 直接复用FilterConfig类型
现在可以直接在React组件Props或处理函数中使用FilterConfig[],无需额外泛型参数:
组件Props示例
type FilterPanelProps = { filters: FilterConfig[]; // onChange参数自动适配不同值类型 onFilterChange: (filterKey: string, values: string[] | number[] | OrderStatus[]) => void; }; const FilterPanel: React.FC<FilterPanelProps> = ({ filters, onFilterChange }) => { return ( <div className="filter-panel"> {filters.map(filter => { // 使用类型守卫区分不同筛选器类型 if (filter.valueType === 'string') { return <CheckBoxList key={filter.key} label={filter.label} options={filter.options} onChange={(values) => onFilterChange(filter.key, values)} />; } if (filter.valueType === 'number') { return <CheckBoxList key={filter.key} label={filter.label} options={filter.options} onChange={(values) => onFilterChange(filter.key, values)} />; } // 枚举类型处理 return <CheckBoxList key={filter.key} label={filter.label} options={filter.options} onChange={(values) => onFilterChange(filter.key, values)} />; })} </div> ); };
筛选处理函数示例
// 自动推断筛选值的类型 function processFilter(filter: FilterConfig, values: (typeof filter.options[number]['value'])[]) { switch (filter.valueType) { case 'string': console.log(`处理字符串筛选:${filter.key},值:`, values); break; case 'number': console.log(`处理数字筛选:${filter.key},值:`, values); break; case 'enum': console.log(`处理枚举筛选:${filter.key},值:`, values); break; } }
关键优势
- 无需手动传入泛型参数,直接使用
FilterConfig[]即可 - TypeScript会自动根据
valueType字段推断每个筛选器的具体类型,保证类型安全 - 可扩展性强,新增其他值类型(如布尔值)或筛选器类型(如select)时,只需新增对应的子类型即可
内容的提问来源于stack exchange,提问作者aravind
相关产品推荐
相关产品推荐

