0Pricing
TypeScript Academy · レッスン

コンポーネントのジェネリクス — 入門

型パラメーター、制約、推論を使って再利用可能なコンポーネントを作り、型付きの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フィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Propsとchildren、イベントハンドラー、refs
  2. Stateとreducer、Contextの型付け
  3. コンポーネントのジェネリクス — 入門
← TypeScript Academyに戻る