カテゴリ: TypeScript 更新日: 2026/05/17

TypeScriptで型を自作!ユーティリティ型とMapped Typesの使い方パターン集

TypeScriptでユーティリティ型を自作するパターン集
TypeScriptでユーティリティ型を自作するパターン集

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

生徒

「TypeScriptを使っていると、すでにある型を少しだけ作り替えたいことがよくあります。例えば、全部の項目を入力必須から任意に変えたいときとか。一つずつ書き直すしかないんでしょうか?」

先生

「そんなときこそ、ユーティリティ型の出番です。TypeScriptには便利な道具があらかじめ用意されていますが、実はそれを自分で作ることもできるんですよ。」

生徒

「型を自分で作る、ですか?難しそうですが、どうすればいいんですか?」

先生

「マッピングという考え方を使うと、驚くほど簡単に型を変換できます。まずは基本から一緒に学んでいきましょう!」

1. 型を再利用する重要性とは?

1. 型を再利用する重要性とは?
1. 型を再利用する重要性とは?

プログラミングにおいて、同じことを何度も書かないというのは非常に大切なルールです。これを「DRY原則」と呼びます。TypeScriptの世界でも、一度作った「型」を色々な場所で使い回すことが推奨されています。

例えば、ユーザー情報を扱う型を作ったとします。会員登録のときは全ての情報が必要ですが、プロフィール更新のときは名前だけ変更したい、という場合があります。このとき、登録用の型と更新用の型を別々に作ってしまうと、後で項目が増えたときに両方の修正が必要になり、ミスの原因になります。そこで、既存の型を変換して新しい型を自動的に作る仕組みが必要になるのです。

2. ユーティリティ型を自作するための基本知識

2. ユーティリティ型を自作するための基本知識
2. ユーティリティ型を自作するための基本知識

TypeScriptには、あらかじめ用意された便利な「ユーティリティ型」がありますが、これらを理解するためには「ジェネリクス」という概念を知っておく必要があります。ジェネリクスとは、型を「変数」のように扱う仕組みのことです。アルファベットのTなどを使って表現されることが多いです。

次に大切なのが「Mapped Types(マップドタイプス)」です。これは、オブジェクトのプロパティ(項目名)を一つずつ取り出して、新しいルールを適用しながら別の型を作る方法です。初心者の方には「型の繰り返し処理」と考えると分かりやすいでしょう。これらを組み合わせることで、自分だけの便利な型製造機を作ることができます。

3. 全ての項目を読み取り専用にする型を作る

3. 全ての項目を読み取り専用にする型を作る
3. 全ての項目を読み取り専用にする型を作る

まずは、オブジェクトの全ての項目を「読み取り専用」にする自作ユーティリティ型を考えてみましょう。読み取り専用にすると、後からその値を書き換えることができなくなります。これは、大事な設定データなどが誤って上書きされるのを防ぐために役立ちます。


type MyReadonly<T> = {
  readonly [P in keyof T]: T[P];
};

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

const myUser: MyReadonly<User> = {
  name: "たろう",
  age: 25
};

// myUser.name = "じろう"; // ここでエラーになります

このコードでは、「keyof T」を使ってUser型にある「name」と「age」という名前を取り出し、それを「P」という変数に入れています。そして、その前に「readonly」をつけることで、全ての項目に鍵をかけているイメージです。

4. 全ての項目を省略可能にする型を作る

4. 全ての項目を省略可能にする型を作る
4. 全ての項目を省略可能にする型を作る

次に、全ての項目を「あってもなくても良い(任意)」という状態にする型を作ってみましょう。これを「Partial(パーシャル)」と呼びます。更新画面などで、一部の項目だけ入力すれば良いという状況で非常に便利です。型定義の項目名の後ろに「ハテナマーク」をつけるのがポイントです。


type MyOptional<T> = {
  [P in keyof T]?: T[P];
};

type Book = {
  title: string;
  price: number;
};

const partialBook: MyOptional<Book> = {
  title: "TypeScript入門"
  // priceがなくてもエラーになりません
};

ここでは「?」記号を使うことで、TypeScriptに対して「この項目は入力しなくても大丈夫だよ」と伝えています。自作することで、標準のPartial型がどのような仕組みで動いているのかがよく分かりますね。

5. 特定の型のみを抽出するフィルター型

5. 特定の型のみを抽出するフィルター型
5. 特定の型のみを抽出するフィルター型

さらに応用として、特定の条件に合うものだけを抜き出す型を作ってみましょう。例えば、たくさんの項目の中から「文字列(string)」だけを抜き出したい場合があります。これには「Conditional Types(条件付き型)」という仕組みを使います。プログラミングのif文のように、「もしこの型ならこれ、そうでなければこれ」という指定ができます。


type OnlyString<T> = T extends string ? T : never;

type MyResult = OnlyString<string | number | boolean>;

// MyResultは string型 になります

「never」というのは、TypeScriptにおいて「何も存在しない」ことを表す特別な型です。条件に合わないものをneverにすることで、実質的にその型をリストから消し去ることができるのです。これを使うと、複雑なデータの絞り込みが可能になります。

6. Mapped Typesでプロパティ名を一括変換する

6. Mapped Typesでプロパティ名を一括変換する
6. Mapped Typesでプロパティ名を一括変換する

Mapped Typesの面白いところは、項目の名前そのものを書き換えることができる点です。例えば、元の型にある項目名の前に「get_」という文字を付け加えた新しい型を作ることができます。これは、データの取得用関数を自動生成する際などに役立ちます。テンプレートリテラル型という機能を使います。


type Getter<T> = {
  [P in keyof T as `get_${string & P}`]: () => T[P];
};

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

type PersonGetters = Getter<Person>;
/*
PersonGettersの中身はこうなります:
{
  get_name: () => string;
  get_age: () => number;
}
*/

「as」というキーワードを使うことで、元の名前「P」を新しい名前にリネームしています。これにより、手作業で一つずつメソッド名を定義する手間が省け、名前の付け間違いというケアレスミスも防ぐことができます。

7. 自作型を組み合わせて高度な型を作る

7. 自作型を組み合わせて高度な型を作る
7. 自作型を組み合わせて高度な型を作る

ここまで紹介したテクニックは、複数を組み合わせることでさらに真価を発揮します。例えば、「読み取り専用にしつつ、全ての項目を必須にする」といった型も作れます。必須にするには、マイナス記号「-?」を使います。これは「ハテナ(任意)の状態を取り除く」という意味になります。

パソコンの操作に例えると、フォルダの属性を一括で変更するような感覚です。ファイル一つ一つを右クリックして変更するのは大変ですが、コマンド一つでフォルダ内の全ファイルを書き換え禁止にするような、強力なパワーがTypeScriptの自作型には備わっています。最初は難しく感じるかもしれませんが、パズルのように型を組み立てる感覚に慣れてくると、プログラミングがどんどん楽しくなっていくはずです。

8. エラーを防ぐための型安全性の向上

8. エラーを防ぐための型安全性の向上
8. エラーを防ぐための型安全性の向上

なぜここまでして型を自作するのでしょうか。それは、開発中の「うっかりミス」をコンピュータに指摘してもらうためです。TypeScriptは、私たちが書いたコードが正しいルールに従っているかを常に監視してくれます。型を細かく定義すればするほど、プログラムを実行する前に間違いを見つけることができます。

特に大規模な開発では、数百、数千のファイルが存在します。誰かが定義した型を別の誰かが使うとき、自作ユーティリティ型によって適切に制限がかけられていれば、使い方の間違いに即座に気づけます。初心者のうちから「どうすればもっと安全な型を作れるか」を意識することは、プロフェッショナルなエンジニアへの第一歩となるでしょう。まずは簡単な「読み取り専用」や「省略可能」の自作から始めて、徐々に複雑な変換に挑戦してみてください。

カテゴリの一覧へ
新着記事
New1
TypeScript
TypeScriptの関数に型をつける方法(引数・戻り値)を初心者向けに徹底解説!
New2
TypeScript
TypeScriptの始め方:開発環境の構築手順【初心者向け】
New3
TypeScript
TypeScriptでExpressのミドルウェアを型安全に定義する方法!バックエンド開発の初心者向け解説
New4
JavaScript
JavaScriptのfilterメソッドで条件に合う要素を抽出する方法
人気記事
No.1
Java&Spring記事人気No1
JavaScript
JavaScriptでフォームの値を取得する方法を徹底解説!valueプロパティの使い道
No.2
Java&Spring記事人気No2
JavaScript
JavaScriptでHTML5バリデーションAPIを使いこなす!初心者でもわかるフォーム入力チェック
No.3
Java&Spring記事人気No3
TypeScript
TypeScriptでコメントを書く正しい書き方と使い分け【初心者向けにやさしく解説】
No.4
Java&Spring記事人気No4
TypeScript
TypeScript学習におすすめの無料教材・リファレンスサイト【初心者向け】
No.5
Java&Spring記事人気No5
JavaScript
JavaScriptのインストール方法まとめ!Windows・Mac・Linux別にステップ解説
No.6
Java&Spring記事人気No6
JavaScript
JavaScriptで要素を削除する方法(removeChild, removeなど)
No.7
Java&Spring記事人気No7
JavaScript
JavaScriptの配列操作でよくあるエラーとその解決法まとめ
No.8
Java&Spring記事人気No8
JavaScript
JavaScriptの現在日時を取得する方法を完全ガイド!初心者でもわかるDate.now()とnew Date()