组件泛型——入门
使用 类型参数、约束和类型推断构建可复用组件;安全地传递带类型的渲染属性和键。
组件泛型——入门 是 CoddyKit 上的免费 TypeScript Academy 课时。 这是第 3 节课,共 3 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 TypeScript Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 TypeScript Academy 课程共包含 3 节课。
入门
目标:使用 <T> 让一个组件适用于多种数据形状。您将传入带类型的渲染属性,约束键,并让 TypeScript 根据使用方式推断 T。
- 泛型属性和渲染函数
- 使用
extends添加约束 - 不依赖任意类型进行键提取
泛型列表<T>
泛型 List<T> 会让项目和渲染函数保持一致。使用者可以传入任意 T;当 T 明确时,类型推断会正常工作。
import React from "react"
type ListProps<T> = { items: T[]; render: (item: T, index: number) => React.ReactNode }
export function List<T>({ items, render }: ListProps<T>) {
return <div style={{ display: "grid", gap: 6 }}>{items.map(render)}</div>
}
export default function App() {
return (
<div style={{ display: "grid", gap: 12 }}>
<List<number> items={[1,2,3]} render={(n) => <span>#{n}</span>} />
<List<{ id: string; name: string }>
items={[{ id: "u1", name: "Ada" }, { id: "u2", name: "Lin" }]}
render={(u) => <strong>{u.name}</strong>}
/>
</div>
)
}使用 extends 添加约束
使用 T extends Keyed 要求提供用于键的 id。如果调用者传入的项目缺少必需字段,就会收到错误。
import React from "react"
type Keyed = { id: string }
type KeyListProps<T extends Keyed> = { items: T[]; render: (item: T) => React.ReactNode }
export function KeyList<T extends Keyed>({ items, render }: KeyListProps<T>) {
return (
<ul>
{items.map((x) => (
<li key={x.id}>{render(x)}</li>
))}
</ul>
)
}
export default function App() {
const users = [{ id: "u1", name: "Ada" }, { id: "u2", name: "Lin" }]
return <KeyList items={users} render={(u) => <span>{u.name}</span>} />
}推断 T
类型参数通常会根据属性推断出来:这里的 T 来自 items。只有在推断不明确时才添加类型注解。
import React from "react"
type GridProps<T> = { items: T[]; columns?: number; render: (item: T) => React.ReactNode }
export function Grid<T>({ items, columns = 2, render }: GridProps<T>) {
const css = { display: "grid", gridTemplateColumns: `repeat(${columns}, 1fr)`, gap: 8 }
return <div style={css as React.CSSProperties}>{items.map(render)}</div>
}
export default function App() {
const products = [
{ sku: "p1", title: "Mouse", price: 25 },
{ sku: "p2", title: "Keyboard", price: 80 }
]
// T is inferred from products; no need to annotate
return <Grid items={products} render={(p) => <span>{p.title} — ${p.price}</span>} />
}渲染辅助工具
提取可复用的 Render<T> 类型,以提高可读性。必要时添加约束(T extends { id: string }),以支持键。
import React from "react"
type Render<T> = (item: T) => React.ReactNode
type TableProps<T extends { id: string }> = { items: T[]; renderRow: Render<T> }
export function Table<T extends { id: string }>({ items, renderRow }: TableProps<T>) {
return (
<table>
<tbody>
{items.map((x) => (
<tr key={x.id}><td>{renderRow(x)}</td></tr>
))}
</tbody>
</table>
)
}
export default function App() {
const rows = [ { id: "1", label: "One" }, { id: "2", label: "Two" } ]
return <Table items={rows} renderRow={(r) => <span>{r.label}</span>} />
}提示与易错点
提示:
- 优先使用类型推断,只在有助于提高可读性时添加类型注解。
- 使用
extends添加约束,以表达要求。 - 不要在泛型渲染属性中使用
any;这会破坏类型安全。
泛型组件检查
快速检查:哪种声明正确地定义了泛型 React 组件?
回顾
回顾:使用 <T> 构建可复用组件,使用 extends 为键添加约束,并让类型推断使代码保持简洁。
常见问题解答
「组件泛型——入门」课时是免费的吗?
是的 — 「组件泛型——入门」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 TypeScript Academy 课程的其余内容,请升级到 CoddyKit PRO。 TypeScript Academy 课程共包含 3 节课。
「组件泛型——入门」这节课中我会学到什么?
使用 类型参数、约束和类型推断构建可复用组件;安全地传递带类型的渲染属性和键。 你通过在浏览器中直接运行的动手代码来练习 TypeScript Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 TypeScript Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 TypeScript Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 3 节。
「组件泛型——入门」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 TypeScript Academy 课中编写并运行代码吗?
能。每节 TypeScript Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。