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

TypeScriptのMapped Typesとジェネリクスの組み合わせ例をわかりやすく解説!初心者でも理解できる型変換の仕組み

TypeScriptのMapped Typesとジェネリクスの組み合わせ例
TypeScriptのMapped Typesとジェネリクスの組み合わせ例

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

生徒

「先生、TypeScriptの“Mapped Types(マップド型)”ってよく聞くんですが、どういうものなんですか?」

先生

「いい質問ですね。Mapped Typesは、既にある型から新しい型を自動的に作る仕組みなんです。つまり、“型のテンプレート”のようなものですね。」

生徒

「なるほど!でも、ジェネリクス(Generics)とどう関係があるんですか?」

先生

「ジェネリクスを使うと、型を柔軟に扱えるようになるんです。Mapped Typesと組み合わせると、より強力な“型の変換”ができるようになりますよ。では、具体的に見ていきましょう!」

1. Mapped Types(マップド型)とは?

1. Mapped Types(マップド型)とは?
1. Mapped Types(マップド型)とは?

TypeScriptのMapped Types(マップド型)とは、既存の型(オブジェクト型)をもとにして、新しい型を動的に作る仕組みです。英語で「Map(マップ)」とは“対応付ける”という意味があり、ある型のプロパティを別の形に変換することができます。

例えば、オブジェクトのすべてのプロパティを「読み取り専用(readonly)」にしたり、「任意(optional)」にしたりすることができます。TypeScriptには標準でReadonly<T>Partial<T>などのマップド型が用意されています。


type User = {
    name: string;
    age: number;
};

type ReadonlyUser = Readonly<User>;

const user: ReadonlyUser = {
    name: "Taro",
    age: 20
};

// user.age = 25; // エラー!読み取り専用なので変更できない

このように、Mapped Typesを使うと元の型をもとに自動的に新しい型を生成できます。

2. ジェネリクスとMapped Typesを組み合わせるとは?

2. ジェネリクスとMapped Typesを組み合わせるとは?
2. ジェネリクスとMapped Typesを組み合わせるとは?

ジェネリクス(Generics)とは、型をパラメータとして扱える仕組みのことです。関数や型、クラスを定義する際に「どんな型でも使えるように」設計できます。

Mapped Typesとジェネリクスを組み合わせると、「どんな型でも変換できる型」を作ることが可能になります。


type Optional<T> = {
    [K in keyof T]?: T[K];
};

type Person = {
    name: string;
    age: number;
};

type OptionalPerson = Optional<Person>;

このコードでは、Optional<T>というジェネリック型を定義しています。Tはどんなオブジェクト型でも受け取ることができ、[K in keyof T]という構文を使って、すべてのプロパティを「任意(?)」にしています。


    // OptionalPersonの型は次のようになります
    {
        name?: string;
        age?: number;
    }

このように、ジェネリクスとMapped Typesを組み合わせることで、「入力された型に応じて動的に別の型を生成する」ことができます。

3. keyofとinの仕組みを理解しよう

3. keyofとinの仕組みを理解しよう
3. keyofとinの仕組みを理解しよう

Mapped Typesでよく使う構文に、keyofinがあります。

  • keyof:オブジェクト型のすべてのキー(プロパティ名)を取得します。
  • in:指定したキー一覧をループして、新しい型を作るために使います。

例えば、次のようなジェネリック型を考えてみましょう。


type Nullable<T> = {
    [K in keyof T]: T[K] | null;
};

type Product = {
    id: number;
    name: string;
};

type NullableProduct = Nullable<Product>;

この例では、すべてのプロパティに| nullを追加しています。つまり、「値が存在しない」場合も許容できる型になります。


    // NullableProduct の型は次のようになります
    {
        id: number | null;
        name: string | null;
    }

このように、Mapped Typesは「すべてのプロパティに対して同じルールを適用したい」ときにとても便利です。

4. 実用的なMapped Typesとジェネリクスの応用例

4. 実用的なMapped Typesとジェネリクスの応用例
4. 実用的なMapped Typesとジェネリクスの応用例

実際の開発では、サーバーとの通信やデータ処理の中で、部分的に更新したり、入力データをバリデーションしたりする場面で活用できます。

たとえば、APIに送る「更新データ」では、すべての項目を送らなくてもいい場合があります。そのようなケースでは、Partial<T>のようなMapped Typesが役立ちます。


function updateUser(user: Partial<{ name: string; age: number }>) {
    if (user.name) {
        console.log("名前を更新します:", user.name);
    }
    if (user.age) {
        console.log("年齢を更新します:", user.age);
    }
}

updateUser({ name: "Hanako" });

    名前を更新します: Hanako

このように、Mapped Typesとジェネリクスを組み合わせることで、「柔軟で安全な型設計」ができるようになります。

5. 独自のMapped Typeを作ってみよう

5. 独自のMapped Typeを作ってみよう
5. 独自のMapped Typeを作ってみよう

自分だけのマップド型を作ることも可能です。例えば、データをすべて文字列に変換する型を作ってみましょう。


type ToStringProps<T> = {
    [K in keyof T]: string;
};

type Info = {
    id: number;
    isActive: boolean;
};

type StringInfo = ToStringProps<Info>;

    // StringInfo の型は次のようになります
    {
        id: string;
        isActive: string;
    }

このように、ジェネリクスを組み合わせることで、どんなオブジェクト型でも簡単に変換できます。まるで「型を自動で作り直すマシン」のように使えるのがMapped Typesの魅力です。

6. Mapped Types × Genericsで型の自動変換を理解しよう

6. Mapped Types × Genericsで型の自動変換を理解しよう
6. Mapped Types × Genericsで型の自動変換を理解しよう

Mapped Typesとジェネリクスを組み合わせることで、TypeScriptの型システムをより柔軟に扱えるようになります。これは、現代的なTypeScript開発において非常に重要な考え方です。型を「動的に生成」することで、より安全でメンテナンス性の高いコードを書くことができます。

まとめ

まとめ
まとめ

Mapped Typesとジェネリクスを通して理解した型変換の考え方

この記事では、TypeScriptにおけるMapped Types(マップド型)ジェネリクス(Generics)を組み合わせた型設計について、基礎から応用までを丁寧に見てきました。Mapped Typesは、すでに存在する型をもとにして、新しい型を自動的に生成する仕組みです。これにより、同じような構造の型を何度も手作業で定義する必要がなくなり、コード全体の見通しが非常に良くなります。

特に重要なのは、「型もプログラムの一部として設計する」という考え方です。TypeScriptでは、実行時の処理だけでなく、型の段階でどこまで安全性を高められるかが大きなポイントになります。Mapped Typesとジェネリクスを使えば、「すべてのプロパティを任意にする」「すべてのプロパティを読み取り専用にする」「すべての値を別の型に変換する」といった処理を、型レベルで一括して表現できます。

keyofとinが果たす役割の重要性

Mapped Typesの中心となる構文が、keyofinです。keyofはオブジェクト型のプロパティ名をすべて取り出し、その集合を型として扱えるようにします。そしてinを使うことで、それらのキーを一つずつ処理しながら新しい型を作成できます。

この仕組みは、JavaScriptの配列処理やオブジェクト操作に少し似ていますが、実際に値を処理しているわけではなく、型そのものを変換している点が大きな特徴です。この発想に慣れることで、TypeScriptの型システムが一気に理解しやすくなります。

実務でMapped Typesが活躍する場面

実際の開発現場では、API通信やフォーム入力、データ更新処理などで「すべての項目が必須ではない」「一部のプロパティだけ変更したい」といった場面が頻繁に登場します。こうしたケースで、Partial<T>や独自に定義したMapped Typesを使うことで、柔軟かつ安全なデータ構造を表現できます。

また、プロジェクトが成長して型の数が増えてきたときにも、Mapped Typesを使って共通ルールを型としてまとめておくことで、修正箇所を最小限に抑えることができます。これは、長期的な保守性を考えるうえで非常に大きなメリットです。

サンプルで振り返るMapped Typesとジェネリクス


type ApiResponse<T> = {
    [K in keyof T]: T[K] | null;
};

type User = {
    id: number;
    name: string;
    email: string;
};

type NullableUser = ApiResponse<User>;

const user: NullableUser = {
    id: 1,
    name: null,
    email: "test@example.com"
};

この例では、ジェネリクスで受け取った型に対してMapped Typesを適用し、すべてのプロパティを「元の型またはnull」に変換しています。こうした型は、APIレスポンスや初期データの表現など、実務で非常によく使われます。

先生と生徒の振り返り会話

生徒

「Mapped Typesって、ただ難しい型の書き方だと思っていましたが、型を自動で作り直す仕組みなんですね。」

先生

「そうですね。既存の型をもとに変換できるので、同じような型を何度も書かずに済むのが大きな利点です。」

生徒

「ジェネリクスと一緒に使うと、どんな型でも対応できるのが便利だと感じました。」

先生

「その気づきはとても大切です。型を部品のように組み立てられるようになると、設計の幅が一気に広がりますよ。」

生徒

「これからは、型もコードと同じように意識して書いていこうと思います。」

先生

「ぜひそうしてください。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の始め方:開発環境の構築手順【初心者向け】