【入門編】 infer キーワード – TypeScript実践ガイド

こんにちは!TypeScriptの世界へようこそ。チーフアーキテクトの私です。

日々、モダンなWeb開発の現場でコードを書いていると、「おっ、これめちゃくちゃ便利だな」と感動する機能に出会うことがあります。今回お話しする `infer`(インファー)キーワード も、まさにその一つ。

TypeScriptを触り始めたばかりの頃って、`string` や `number` といった基本の型から始まり、配列やオブジェクト、そしてちょっと背伸びして「条件分岐の型(Conditional Types)」なんかを勉強すると、もう頭がパンクしそうになりますよね。

「`infer`って何やら難しそうな名前だし、公式ドキュメントを読んでも呪文にしか見えない……」

そんな風に思っていませんか? 大丈夫ですよ、安心してください。今日ここで、あなたのそのモヤモヤをスッキリ解消してみせます。難しい専門用語はいったん脇に置いて、身近な例え話からゆっくり紐解いていきましょうか。

—

1. `infer` って、ぶっちゃけどんなイメージ?

まず、`infer` という英単語の意味を調べてみると、「推論する」「察する」という意味があります。

TypeScriptにおける `infer` は、まさに「パズルや箱の中身を、外からサクッと見破る透視グラス」のようなものです。

ちょっと想像してみてください。
目の前に、中身が見えない「お楽しみ袋(プレゼントボックス)」が置いてあります。あなたには、その袋の「包み紙(大元の型)」は分かっているけれど、「中に入っている具体的なおもちゃ(部分的な型)」が何なのか分からない状態です。

ここで `infer` の登場です。
`infer` は、そのお楽しみ袋の隙間を覗き込んで、「あ、中に入っているのは `string` だね!じゃあ、この中身を一時的に `T` という名前の変数としてキープしておくよ!」と、自動で察知して取り出してくれるんです。

—

2. なぜ `infer` が必要なの?(これまでの壁)

TypeScriptの「条件分岐の型(Conditional Types)」を使うと、こんな書き方ができます。

// もし型 U が string なら A、そうじゃなければ B を返す、みたいなやつです
type IsString = T extends string ? “文字列だよ” : “文字列じゃないよ”;

これは、「型 `T` が `string` かどうか」を外側から判定するシンプルなルールです。
しかし、現場でよくあるリアルな悩みとして、「中身のパーツだけを取り出したい」という状況があります。

例えば、「関数の戻り値の型だけを抜き出したい」とか、「配列の中に入っている要素の型だけを取り出したい」といったケースです。

「関数の型そのもの」は分かっているのに、その中にある「返り値の型」だけをピンポイントで指し示す名前がついていない……。そんな絶望的な状況を救い出すのが、`infer` キーワードなのです。

—

3. コードで体感してみよう!一番わかりやすい例

百聞は一見にしかず。みんな大好き、関数の「戻り値の型」をこっそり抜き取る型を作ってみましょう。

エディタを開いて、以下のコードをコピペしてみてください。

/

  • 関数の戻り値(返り値)の型だけをこっそり抜き取るカスタム型
  • これが infer の定番の使い方です!

/
type MyReturnType = T extends (…args: any[]) => infer R ? R : never;

// — 実際に使ってみましょう —

// 1. 文字列を返す関数
function getUsername() {
return “Taro Yamada”;
}

// 2. この関数の「戻り値の型」を MyReturnType を使って自動で暴きます
type ResultType = MyReturnType;
// 👆 ResultType の中身は、自動的に “string” になります!すっごい!

コードの解説(ここが重要!)

`T extends (…args: any[]) => infer R ? R : never` の部分を、日本語でゆっくり翻訳してみますね。

1. `T extends (…args: any[]) =>`
「もし、渡された型 `T` が『何らかの引数を受け取って何かを返す関数』の形をしていたら……」
2. `infer R`
「その関数の『戻り値(返り値)』の部分を、`R` という名前の一時的な変数に当てはめて(推論して)ちょーだい!」
3. `? R : never`
「もしうまく見破れたら、その `R`(戻り値の型)をそのまま返す! もし関数じゃなかったら `never`(あり得ない型)にするね」

このように、`infer` の後ろに書いたアルファベット(ここでは `R`)は、「新しく作り出した変数」になります。Conditional Types の世界でだけ使える、魔法の一時変数なんです。

—

4. もう一つの例:配列から中身を救い出す

もう一つ、Web制作でもよくある「配列のラッパーから中身を取り出す」パターンを見てみましょう。

/

  • 配列の型から、中身の要素の型だけを抜き出すカスタム型

/
type UnpackArray = T extends (infer U)[] ? U : T;

// 使い方の例
type StringArray = string[];

// UnpackArray に渡すと、配列のブラケット([])が剥がれて中身の string だけが残ります
type Extracted = UnpackArray;
// 👆 Extracted の型は “string” になります!

「配列の箱(`[]`)」という構造から、`infer U` を使って中の要素(`U`)をスポッと抜き出す。この感覚、なんとなく掴めてきたのではないでしょうか?

—

5. 初学者のあなたが「つまずきやすいポイント」と温かいフォロー

ここで、少しだけ現場のリアルな本音をお伝えしておきます。

実は、この `infer` キーワード、初学者のうちは自分でゼロからガリガリ書く機会はそこまで多くありません。
「えっ、じゃあ覚えなくていいの?」と思われるかもしれませんが、そうではありません。

なぜなら、世の中の便利なライブラリ(React、Vue、各種ユーティリティライブラリなど)の型定義の中には、この `infer` が大量に使われているからです。

「なんかこのライブラリ、関数を渡すだけで自動的に戻り値の型を推論して補完してくれるぞ……? 神かよ……」

そう思った時、その裏側でこっそり働いているのがこの `infer` なのです。仕組みを知っておくことで、エラーが出たときに「あ、今ライブラリの内部で型の推論がうまくいってないんだな」と冷静に原因を推測できるようになります。

最初は「`infer` って、型の中で『ここ何だっけ?』って一時的に変数を作るためのマジックワードなんだな」くらいのふわっとした理解で100点満点です。

—

おわりに

今回は、TypeScriptのちょっと奥まった機能である `infer` キーワードについて、身近な例えを交えて解説しました。

最初は難解に見える高度な型定義も、一つひとつのパーツに分解して「何を推論しようとしているのか」を追っていくと、先人たちの美しい工夫や優しさに気づけるようになります。TypeScriptの型システムは、私たち開発者の「うっかりミス」を防ぐために、裏側で一生懸命頭を働かせてくれている最高の相棒です。

焦らず、自分のペースで一歩ずつ、TypeScriptと仲良くなっていきましょうね。
それでは、次の現場でお会いしましょう!チーフアーキテクトでした。

コメント

タイトルとURLをコピーしました