如何为可复用React CRUDTable组件实现外部类型自动推断
问题原因
你之前的写法没有将tableData的类型和泛型参数绑定,TS无法建立tableData条目类型和createCall入参类型的关联,所以无法自动推断。
正确实现方案
1. 定义带关联泛型的Props接口
泛型T代表单条表格行数据的类型,将tableData和createCall的类型都绑定到同一个泛型上:
interface IProps<T> { createCall: (data: T) => any; tableData: T[]; // 其他操作方法比如editCall、deleteCall都可以沿用T作为入参类型 }
2. 实现泛型CRUDTable组件
组件声明泛型参数,TSX语法下需要在泛型参数后加逗号避免被识别为JSX标签:
export const CRUDTable = <Data,>(props: IProps<Data>) => { return ( <div> {props.tableData.map((entry, index) => { // 这里entry会自动被推断为Data类型,不需要额外声明类型 return ( <div key={index} onClick={() => props.createCall(entry)}> {/* 表格行渲染逻辑 */} </div> ) })} </div> ) }
3. 可选:给泛型加公共字段约束
如果你的表格数据要求必须存在id这类公共字段,可以给泛型增加约束,避免内部访问公共属性时报类型错误:
// 约束Data必须包含id字段 export const CRUDTable = <Data extends { id: number | string },>(props: IProps<Data>) => { // 内部访问entry.id不会报错 }
使用效果
在父组件中使用时,TS会自动根据传入的tableData类型推导出泛型的实际类型,自动给createCall的入参设置对应类型:
const ParentComponent = () => { const tableData = [ { id: 1, name: 'David', address: 'some address'}, { id: 2, name: 'Angela', address: 'some address 2'}, { id: 3, name: 'Arthur', address: 'some address3'}, ] return ( <CRUDTable tableData={tableData} // data会自动被推断为 { id: number; name: string; address: string } 类型 createCall={(data) => { // 输入data.时会自动提示id、name、address属性,类型错误会实时校验 return fetch('/api/create', { method: 'POST', body: JSON.stringify(data) }) }} /> ) }
内容的提问来源于stack exchange,提问作者Norayr Ghukasyan
相关产品推荐
相关产品推荐

