コンポーネントのジェネリクス — 入門
型パラメーター、制約、推論を使って再利用可能なコンポーネントを作り、型付きのrender propsとキーを安全に渡します
「コンポーネントのジェネリクス — 入門」はCoddyKit上の無料TypeScript Academyレッスンです。 これはレッスン3/3です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはTypeScript Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 TypeScript Academyコースには全3レッスンが含まれています。
導入
目標: <T> を使って、さまざまなデータ形状に対応できる 1 つのコンポーネントを作成します。型付きの render prop を渡し、キーに制約を設け、利用方法から TypeScript に T を推論させます。
- ジェネリックな props と render 関数
extendsによる制約- any を使わないキーの抽出
ジェネリック List<T>
ジェネリックな List<T> によって、items と render の型を一致させられます。利用側は任意の 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 の推論
型パラメーターは通常 props から推論されます。ここでは 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 ヘルパー
分かりやすさのために、再利用可能な 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で制約を設けてください。 - ジェネリックな render prop で
anyを使わないでください。安全性が失われます。
ジェネリックコンポーネントの確認
クイックチェック: ジェネリックな React コンポーネントを正しく定義している宣言はどれですか。
まとめ
まとめ: <T> を使って再利用可能なコンポーネントを作り、extends でキーの要件を制約し、推論によってコードを簡潔に保ちます。
よくある質問
「コンポーネントのジェネリクス — 入門」レッスンは無料ですか?
はい。「コンポーネントのジェネリクス — 入門」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、TypeScript Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 TypeScript Academyコースには全3レッスンが含まれています。
「コンポーネントのジェネリクス — 入門」で何を学びますか?
型パラメーター、制約、推論を使って再利用可能なコンポーネントを作り、型付きのrender propsとキーを安全に渡します ブラウザで直接実行するハンズオンコードでTypeScript Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
TypeScript Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのTypeScript Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/3です。
「コンポーネントのジェネリクス — 入門」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このTypeScript Academyレッスンでコードを書いて実行できますか?
はい。すべてのTypeScript Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- Propsとchildren、イベントハンドラー、refs
- Stateとreducer、Contextの型付け
- コンポーネントのジェネリクス — 入門