TypeScript泛型正确用法?组件开发遇'title'属性不存在错误
你的实现方向是正确的
用泛型开发通用组件来适配不同类型的服务器数据,这个思路完全没问题——泛型本来就是用来提升组件复用性、让组件能灵活处理多种数据类型的方案。
修复"Property 'title' does not exist"错误
你说的原因完全对:IData<T> 只定义了 id 字段,而 TableTest 里你试图访问 todo.title,TypeScript 会因为类型不匹配报错。下面是几种可行的修复方案:
方案1:直接让columns接收T类型数组
既然已经通过泛型 T 指定了具体数据类型(比如你的 ITodos),没必要再用 IData<T> 做一层包装,直接把 columns 的类型改成 T[] 即可:
// 修改TableTest的类型定义 export interface ITable<T> { columns: T[], } export default function TableTest<T>(props: ITable<T>) { return ( <div> {props.columns.map((todo) => <div>{todo.title}</div>)} </div> ); }
这个方案简单直接,但缺点是如果后续要给没有 title 字段的数据类型用这个组件,代码会再次报错,通用性有限。
方案2:给泛型T添加字段约束
如果你的表格组件要求所有传入的数据都必须包含某些固定字段(比如 id 和 title),可以给泛型添加类型约束:
// 定义基础数据接口,规定必须包含的字段 interface IBaseData { id: number; title: string; } // 让泛型T继承IBaseData,确保T包含title字段 export interface ITable<T extends IBaseData> { columns: T[], } export default function TableTest<T extends IBaseData>(props: ITable<T>) { return ( <div> {props.columns.map((todo) => <div>{todo.title}</div>)} </div> ); }
这样只有符合 IBaseData 结构的数据类型才能使用该组件,从根源上避免了类型错误。
方案3:传入自定义渲染函数(推荐)
如果想要组件真正通用,适配任意结构的数据类型,最优解是让父组件传入渲染每一行的函数,由父组件决定如何渲染具体数据:
// 更新ITable接口,增加renderItem函数 export interface ITable<T> { columns: T[], renderItem: (item: T) => React.ReactNode; } export default function TableTest<T>(props: ITable<T>) { return ( <div> {props.columns.map((item) => ( <div key={item.id}>{props.renderItem(item)}</div> ))} </div> ); }
然后在App组件中使用时,传入针对 ITodos 的渲染逻辑:
const App = () => { return ( <div> <TableTest<ITodos> columns={todos} renderItem={(todo) => <div>{todo.title}</div>} /> </div> ) }
这种方式让组件完全脱离具体的数据结构,不管后续传入什么类型的数据,只要父组件提供对应的渲染函数就能正常工作,复用性最强。
内容的提问来源于stack exchange,提问作者Anton
相关产品推荐
相关产品推荐

