カテゴリ: TypeScript 更新日: 2025/12/10

TypeScriptでフォーム・APIレスポンスなど共通型を汎用化する方法

TypeScriptでフォーム・APIレスポンスなど共通型を汎用化する方法
TypeScriptでフォーム・APIレスポンスなど共通型を汎用化する方法

先生と生徒の会話形式で理解しよう

生徒

「先生、TypeScriptでフォームやAPIレスポンスの型を毎回同じように書くのが面倒なんですが、もっと楽にできますか?」

先生

「とても良い質問ですね。TypeScriptでは“ジェネリクス(Generics)”を使えば、共通の型を汎用的に使い回すことができますよ。」

生徒

「ジェネリクスって何ですか?なんだか難しそうな名前ですね…。」

先生

「大丈夫ですよ。ジェネリクスは“型を後から指定できる仕組み”のことです。フォームデータやAPIレスポンスの型を共通化するのにとても便利なんです。」

生徒

「なるほど!じゃあ、どうやって使うのか教えてください!」

先生

「それでは、具体的な使い方を見ていきましょう!」

1. ジェネリクスで型を使い回すとは?

1. ジェネリクスで型を使い回すとは?
1. ジェネリクスで型を使い回すとは?

TypeScriptのジェネリクス(Generics)とは、「どんな型でも受け取れるけれど、使うときに具体的な型を指定できる」という仕組みです。
英語の「Generic(一般的な)」という言葉の通り、共通化された型を作るのに使います。

たとえば、ユーザー登録フォーム・商品登録フォームなど、似たようなデータ構造を扱うとき、毎回別々に型を定義していると重複が増えてしまいます。そんなときに、ジェネリクスを使うと共通化できて便利です。

2. フォームデータをジェネリクスで共通化する例

2. フォームデータをジェネリクスで共通化する例
2. フォームデータをジェネリクスで共通化する例

たとえば、「フォームの入力結果をまとめるオブジェクト」を共通化して扱いたいとします。以下のようなコードで、どんなフォームでも使えるようにできます。


type FormData = {
    id: string;
    data: T;
    submittedAt: Date;
};

// ユーザー登録フォーム用
type UserForm = {
    name: string;
    email: string;
};

// 商品登録フォーム用
type ProductForm = {
    title: string;
    price: number;
};

// 使用例
const userFormData: FormData<UserForm> = {
    id: "u001",
    data: { name: "太郎", email: "taro@example.com" },
    submittedAt: new Date(),
};

const productFormData: FormData<ProductForm> = {
    id: "p001",
    data: { title: "ノートPC", price: 120000 },
    submittedAt: new Date(),
};

このように、<T> の部分に「型の引数」を渡して使います。FormData<UserForm>FormData<ProductForm>のように書くことで、それぞれのフォームに応じた型を安全に扱うことができます。

3. APIレスポンスの型を汎用化して使う

3. APIレスポンスの型を汎用化して使う
3. APIレスポンスの型を汎用化して使う

次に、APIからデータを取得する場面でもジェネリクスは大活躍します。
サーバーから返ってくるデータ構造が似ている場合、毎回型を作るのは大変ですよね。そんなときに共通のレスポンス型をジェネリクスで定義します。


type ApiResponse = {
    success: boolean;
    message: string;
    data: T;
};

// ユーザー情報APIの例
type User = {
    id: number;
    name: string;
};

// 商品情報APIの例
type Product = {
    id: number;
    title: string;
    price: number;
};

// 使用例
const userResponse: ApiResponse<User> = {
    success: true,
    message: "ユーザー情報取得成功",
    data: { id: 1, name: "花子" },
};

const productResponse: ApiResponse<Product> = {
    success: true,
    message: "商品情報取得成功",
    data: { id: 10, title: "キーボード", price: 3500 },
};

ApiResponseの中身は同じですが、Tの部分を変えるだけで、どんな種類のレスポンスでも対応できます。
これによって、コードの再利用性がぐっと上がり、保守性も良くなります。

4. 関数でもジェネリクスを使ってみよう

4. 関数でもジェネリクスを使ってみよう
4. 関数でもジェネリクスを使ってみよう

ジェネリクスは型だけでなく、関数にも使うことができます。
たとえば、APIレスポンスを処理する共通関数を作るときに便利です。


function handleResponse<T>(response: ApiResponse<T>): void {
    if (response.success) {
        console.log("成功:", response.data);
    } else {
        console.error("失敗:", response.message);
    }
}

handleResponse(userResponse);
handleResponse(productResponse);

このように書くことで、どんなデータ型でも安全に扱える関数が完成します。関数に渡されるデータの型が自動的に推論されるため、型ミスを防げます。

5. 実践的な使い方:フォーム入力のバリデーション

5. 実践的な使い方:フォーム入力のバリデーション
5. 実践的な使い方:フォーム入力のバリデーション

さらに一歩進んだ使い方として、フォーム入力のバリデーション(入力内容のチェック)もジェネリクスを使って共通化できます。


function validateForm<T>(form: FormData<T>): boolean {
    if (!form.id || !form.data) {
        console.error("フォームのデータが正しくありません");
        return false;
    }
    console.log("フォームデータが正しい形式です");
    return true;
}

validateForm(userFormData);
validateForm(productFormData);

このように、型の部分だけを入れ替えることで、どんな種類のフォームでも共通の関数でチェックできるようになります。これがジェネリクスの最大の強みです。

6. ジェネリクスで型の再利用性を高めよう

6. ジェネリクスで型の再利用性を高めよう
6. ジェネリクスで型の再利用性を高めよう

TypeScriptでフォームやAPIレスポンスを扱うとき、ジェネリクスを使えば「一つの型を何度も再利用」できます。
開発の効率が上がるだけでなく、型安全(型が正しいことを保証)なコードを書くことができます。ジェネリクスは最初は少し難しく感じますが、「型を後から指定できる便利な仕組み」と覚えておくと理解しやすいですよ。

まとめ

まとめ
まとめ

TypeScriptのジェネリクスについて学んできました。ジェネリクスとは「型を後から指定できる仕組み」で、フォームデータやAPIレスポンス、関数の引数、オブジェクトなど、様々な場面で共通の型を汎用的に使い回すことができます。これにより、コードの再利用性が高まり、同じ構造のデータを何度も書く必要がなくなります。さらに、型安全性も確保できるため、間違った型のデータを扱うリスクを減らせます。

フォームデータの場合、FormData<T>のように型の引数を渡すことで、ユーザー登録フォームや商品登録フォームなど、異なるデータ構造でも共通の型を使い回せます。また、APIレスポンスではApiResponse<T>のように定義することで、取得するデータの型を後から指定でき、関数に渡すときも安全に扱えます。これにより、開発効率が上がるだけでなく、コードレビューや保守の際にもわかりやすくなります。

関数にジェネリクスを使う場合も、データ型が自動で推論されるため、型ミスやバグを未然に防げます。さらに、フォームのバリデーションなど、入力チェックを共通化することで、どんな種類のフォームでも同じ関数で安全に処理できます。このように、ジェネリクスを活用することで、TypeScriptのコードはより安全で効率的に書けるようになります。

ジェネリクスの具体例


// 汎用フォーム型
type FormData<T> = {
    id: string;
    data: T;
    submittedAt: Date;
};

// 共通バリデーション関数
function validateForm<T>(form: FormData<T>): boolean {
    if (!form.id || !form.data) {
        console.error("フォームのデータが正しくありません");
        return false;
    }
    console.log("フォームデータが正しい形式です");
    return true;
}

// 使用例
type UserForm = { name: string; email: string; };
const userForm: FormData<UserForm> = { id: "u001", data: { name: "太郎", email: "taro@example.com" }, submittedAt: new Date() };
validateForm(userForm);
先生と生徒の振り返り会話

生徒

「ジェネリクスを使うと、同じ型を何度も書かなくていいからすごく便利ですね。フォームもAPIレスポンスも、共通化できるんですね。」

先生

「その通りです。ジェネリクスを使えば、どんな型のデータにも対応できる汎用性の高いコードが書けます。さらに型安全性も確保できるので、バグを減らす効果もあります。」

生徒

「関数にも使えるから、どのフォームやAPIレスポンスでも同じ関数で処理できるんですね。型の引数を入れるだけで便利に使えるんだ。」

先生

「その通りです。最初は少し難しく感じるかもしれませんが、型を共通化して再利用する考え方を覚えると、TypeScriptでの開発が格段に効率よくなります。学んだことを実際にプロジェクトで試してみてください。」

カテゴリの一覧へ
新着記事
New1
TypeScript
TypeScriptでパスエイリアスを設定する方法!baseUrlとpathsでコードをスッキリ整理
New2
JavaScript
JavaScriptのfor文の書き方を初心者向けにやさしく解説
New3
JavaScript
JavaScriptの関数でよくあるエラーとその解決法まとめ
New4
JavaScript
JavaScriptのイベント処理でよくあるエラーとその対処法
人気記事
No.1
Java&Spring記事人気No1
JavaScript
JavaScriptのインストール方法まとめ!Windows・Mac・Linux別にステップ解説
No.2
Java&Spring記事人気No2
JavaScript
JavaScriptのマウスイベントの使い方(click, mouseoverなど)
No.3
Java&Spring記事人気No3
JavaScript
JavaScriptのtoStringとString関数の違いを初心者向けに解説
No.4
Java&Spring記事人気No4
JavaScript
JavaScriptの純粋関数(pure function)と副作用の違いを理解しよう
No.5
Java&Spring記事人気No5
JavaScript
JavaScriptプログラムの実行方法まとめ!ブラウザ・Node.js・コンソールの使い方
No.6
Java&Spring記事人気No6
JavaScript
JavaScriptで文字列をforループで1文字ずつ処理する方法!初心者向け解説
No.7
Java&Spring記事人気No7
TypeScript
TypeScript学習におすすめの無料教材・リファレンスサイト【初心者向け】
No.8
Java&Spring記事人気No8
TypeScript
TypeScriptの始め方:開発環境の構築手順【初心者向け】