标准答案
- 泛型组件常用于 item 类型不固定但交互模式固定的组件,例如 Table<T>、Select<T>、List<T>。
- 泛型参数应尽量从 data、value、columns、renderItem 等 props 自动推导。
- 约束泛型时可以使用 extends,保证组件内部能访问必要字段,例如 id 或 key。
- forwardRef、memo 和泛型组合时容易丢失推导,需要显式声明函数签名或做类型包装。
- 类型设计要服务调用体验,过度复杂的条件类型会让错误信息难读。
题目解析
这道题考的是类型建模。泛型的价值是复用组件逻辑,同时保留业务数据类型。
如果每次使用组件都要手动写很长的泛型参数,通常说明 props 设计没有让 TypeScript 推导出足够信息。
复杂组件可以先保证核心 props 推导稳定,再逐步处理 ref、默认值和受控状态等边界。
代码示例
下面的列表组件通过 items 推导 T,再把 T 传给 renderItem。
TSX
type DataListProps<T extends { id: string }> = {
items: T[]
renderItem: (item: T) => ReactNode
}
function DataList<T extends { id: string }>({ items, renderItem }: DataListProps<T>) {
return (
<ul>
{items.map(item => (
<li key={item.id}>{renderItem(item)}</li>
))}
</ul>
)
}常见误区
- 把泛型写得过宽,组件内部实际依赖 id、label 等字段却没有约束。
- 所有 props 都用 any,表面通用但失去类型保护。
- memo 或 forwardRef 包装后没有保留泛型签名,调用方推导变差。