如何在TypeScript中为泛型接口创建通用实现?
基于DRY原则实现React Virtuoso泛型表格组件配置
核心思路
既然多个VirtuosoTableComponents实现仅类型和列配置不同,其余逻辑完全一致,我们可以通过泛型工厂函数封装通用逻辑,传入不同的类型参数和列配置即可生成对应版本的组件配置。
实现步骤
1. 确认基础类型定义
首先确保列配置类型是泛型的,适配不同行数据类型:
// 定义列的通用类型,T为行数据的具体类型 type TableColumn<T> = { key: keyof T; label: string; render?: (value: T[keyof T]) => React.ReactNode; // 可添加其他列属性,如宽度、对齐方式等 };
2. 编写泛型工厂函数
创建通用函数封装所有重复的组件逻辑,接收列配置后返回对应类型的VirtuosoTableComponents:
import { VirtuosoTableComponents } from 'react-virtuoso'; import TableHeader from './TableHeader'; // 你的自定义表头组件 import TableRow from './TableRow'; // 你的自定义行组件 // 泛型函数:生成对应数据类型的Virtuoso表格组件配置 export function createVirtuosoTableComponents<T>(columns: TableColumn<T>[]): VirtuosoTableComponents<T> { return { // 通用表头实现 Header: () => <TableHeader columns={columns} />, // 通用行实现,item自动推断为T类型 Row: ({ item }) => <TableRow item={item} columns={columns} />, // 如需其他通用组件(如空状态占位符),可在此统一定义 EmptyPlaceholder: () => <div>No data available</div> }; }
3. 调用生成具体配置
使用时只需传入对应列配置,TypeScript可自动推断数据类型,也可显式指定:
// 假设你已有BookList、Book类型及对应列配置 import { BookList, bookListColumns } from './data-context'; import { Book, bookColumns } from './data-context'; // 生成BookList类型的组件配置(显式指定类型) const VirtuosoTableComponents_booklists = createVirtuosoTableComponents<BookList>(bookListColumns); // 生成Book类型的组件配置(TypeScript自动推断T为Book) const VirtuosoTableComponents_books = createVirtuosoTableComponents(bookColumns); // 在VirtuosoTable中使用 <VirtuosoTable data={bookListData} components={VirtuosoTableComponents_booklists} /> // 也可直接内联调用,简化代码 <VirtuosoTable data={bookData} components={createVirtuosoTableComponents(bookColumns)} />
关键优势
- 完全遵循DRY原则:所有通用逻辑仅编写一次,彻底消除重复代码
- 类型安全:TypeScript自动校验行数据与列配置的类型匹配,避免类型错误
- 扩展性强:如需修改表头、行的通用逻辑,只需在工厂函数中修改一次,所有生成的配置会同步更新
内容的提问来源于stack exchange,提问作者Dani Muñoz
相关产品推荐
相关产品推荐

