React+TypeScript:如何为表格组件的回调处理器使用泛型
泛化React表格组件的TypeScript实现修复方案
核心思路是通过泛型约束确保表格数据必须包含id属性,同时让TypeScript自动推断自定义数据类型,避免使用Record或any导致的类型丢失。
修复后的完整代码
import React from 'react'; // 定义基础约束:所有表格数据必须包含id字段 type WithId = { id: string | number }; // 列配置泛型,T表示表格数据的具体类型(必须满足WithId约束) type Column<T extends WithId> = { key: keyof T; label: string; // 修复getContent的类型:参数为具体的T类型,返回React节点 getContent: (tableItem: T) => React.ReactNode; }; // 表格组件Props泛型,绑定同一数据类型T type TableProps<T extends WithId> = { // 修复data的类型:T类型的数组,自动推断具体结构 data: T[]; columns: Column<T>[]; }; // 泛化表格组件实现 const Table = <T extends WithId>({ data, columns }: TableProps<T>) => { return ( <table> <thead> <tr> {columns.map((column) => ( <th key={column.key.toString()}>{column.label}</th> ))} </tr> </thead> <tbody> {data.map((item) => ( <tr key={item.id}> {columns.map((column) => ( <td key={column.key.toString()}> {column.getContent(item)} </td> ))} </tr> ))} </tbody> </table> ); }; // 示例:自定义数据类型 type Person = WithId & { name: string; age: number; email: string; }; // 使用表格组件 const App = () => { const persons: Person[] = [ { id: 1, name: '张三', age: 28, email: 'zhangsan@example.com' }, { id: 2, name: '李四', age: 32, email: 'lisi@example.com' }, ]; const columns: Column<Person>[] = [ { key: 'name', label: '姓名', // 此处tableItem会自动识别为Person类型,拥有name/age/email等属性 getContent: (tableItem) => <span>{tableItem.name}</span>, }, { key: 'age', label: '年龄', getContent: (tableItem) => <span>{tableItem.age}</span>, }, { key: 'email', label: '邮箱', getContent: (tableItem) => <a href={`mailto:${tableItem.email}`}>{tableItem.email}</a>, }, ]; return <Table data={persons} columns={columns} />; }; export default App;
关键修复点说明
- 基础约束类型
WithId:统一规定所有表格数据必须包含id字段,通过T extends WithId确保泛型类型符合要求。 - 列配置
Column<T>:将泛型T绑定到列的getContent回调参数,这样当传入具体数据类型(如Person)时,TypeScript会自动推断tableItem的完整类型。 - 表格Props
TableProps<T>:让data字段的类型为T[],与列配置的泛型保持一致,实现类型联动。
这样在使用自定义数据类型时,列回调中的tableItem会自动拥有该类型的所有属性,不会出现类型识别错误的问题。
内容的提问来源于stack exchange,提问作者Robin Wieruch
相关产品推荐
相关产品推荐

