TypeScriptの「infer」って何?魔法の呪文で型を自在に操ろう!✨
Web制作・開発の世界へようこそ!TypeScriptって、最初はちょっと難しそうに感じるかもしれませんよね。「型」とか「ジェネリクス」とか、聞いただけで頭がクラクラ…なんて声もよく聞きます。でも大丈夫!一つずつ、ゆっくり、そして何より楽しく学んでいきましょう。
今日は、TypeScriptのちょっと魔法みたいなキーワード、「`infer`」についてお話しします。これが使えるようになると、今まで「え、どうやってこの型を取り出すの?」って悩んでいたことが、スッキリ解決するんですよ。まるで、宝箱の鍵を開けるような感覚かもしれません!
そもそも「型推論」って、なんで大事なの?
TypeScriptを触り始めたばかりのあなたは、きっとこんな経験をしたことがあるはずです。
- 「え、この変数、本当は数値なのに文字列として扱われちゃってる!」
- 「この関数の戻り値、もっと詳しく型を指定したいんだけど…」
そう、TypeScriptは「型」をしっかり定義することで、コードの間違いを未然に防ぎ、開発をスムーズに進めるための強力なツールなんです。でも、毎回すべての型を細かく指定するのは、正直言って面倒くさいこともありますよね。
そこで登場するのが「型推論」です。TypeScriptは、コードの書き方から「あ、この型はきっとこうだろうな」って、賢く推測してくれるんです。例えば、こんな感じ。
let message = “こんにちは、世界!”; // TypeScriptはmessageがstring型だと推論してくれます
let count = 100; // countはnumber型だと推論してくれます
この自動で推論してくれる機能、とっても便利ですよね!でも、もっと複雑な場面では、TypeScriptも「うーん、これはどうやって取り出せばいいんだろう?」って困ってしまうことがあります。
inferキーワード:TypeScriptの「型探偵」🕵️♀️
そんな時に、私たちが「おい、TypeScriptくん、この中からあの型を取り出してほしいんだ!」と、具体的に指示を出すための秘密兵器が、`infer`キーワードなんです。
`infer`は、Conditional Types(条件型)という仕組みの中で使われます。Conditional Typesって聞くと、また難しそう…と思いますよね?でも、これも例え話で考えると、意外とシンプルなんです。
条件型のお買い物シミュレーション🛍️
例えば、あなたがスーパーで「このリンゴ、甘かったら買う、酸っぱかったらやめとく」と決めているとしましょう。
この「もし〜〜だったら〜〜する」という考え方が、Conditional Typesの基本なんです。TypeScriptで書くと、こんなイメージです。
// Tは「もし〜〜」の部分、Uは「〜〜だったら〜〜する」の部分
type If
// 例:もしtrueなら’Yes’、falseなら’No’を返す
type Result = If
type AnotherResult = If
このConditional Typesの中で、`infer`は「型を推論する(infer)」という役割を果たします。
inferって、具体的にどう使うの?
`infer`は、Conditional Typesの`extends`の右側(つまり、推論したい対象)で使われます。そして、推論された型は、`infer`の後に名前をつけて、その型が使いたい場所で使えるようになります。
例えるなら、宝箱(推論したい対象)があって、その中に「秘密の宝石」(抽出したい型)が入っているのを、`infer`という「魔法の虫眼鏡」で覗き見て、「よし、この宝石は『MyGem』と名付けよう!」って決めるようなイメージです。
1. 関数の「戻り値の型」を抜き出す!🚀
よくあるのが、「この関数が返す値の型だけを知りたい!」というケースです。
例えば、`getUserName`という関数があって、それが`string`を返すとします。この`string`という型だけを抜き出したい!
// 元になる関数
function getUserName(): string {
return “Taro Yamada”;
}
// Tはこの関数全体を表すとします
type GetReturnType
ここで`infer`の出番です!`T`が関数である場合に、その関数の「戻り値の型」を`infer R`として推論し、その`R`を返すようにします。
// Tは関数型を表す。(…args: any[]) => any は「引数は何でもよくて、戻り値も何でもいい関数」という意味
// Rは、その関数の「戻り値の型」を推論するための仮の名前
type GetReturnType
// getUserName関数の型だけを渡してみる
type UserNameType = GetReturnType
// 実際に型を確認してみると…
let name: UserNameType = “Jiro Tanaka”; // OK
// let age: UserNameType = 30; // Error! string型じゃないと怒られる
どうでしょう?`getUserName`という関数から、その戻り値である`string`型だけを、まるで型専用の「抽出機」のように取り出すことができました。`typeof getUserName`としているのは、関数そのものの型を取得するためです。
2. 配列の「要素の型」を抜き出す!📦
次に、配列から要素の型だけを取り出すケースを考えてみましょう。
例えば、`users`という配列があり、その要素が`string`型だとします。この`string`型だけを抜き出したい!
// 元になる配列の型
type UserList = string[];
// Tはこの配列型を表すとします
type GetElementType
ここで`infer`が登場!`T`が配列型(`[]`で終わる型)である場合に、その配列の「要素の型」を`infer Element`として推論し、`Element`を返します。
// UserList(string[])を渡してみる
type UserType = GetElementType
// 実際に型を確認してみると…
let userName: UserType = “Alice”; // OK
// let userAge: UserType = 25; // Error! string型じゃないと怒られる
// numbersという配列型で試してみる
type NumberList = number[];
type NumberType = GetElementType
`infer`のおかげで、`string[]`という型から`string`型を、`number[]`という型から`number`型を、まるで「箱から中身だけを取り出す」かのように、簡単に抽出できるようになりました。
inferのすごいところ:単一の型だけでなく、複数の型も推論できる!🌟
実は、`infer`はもっと賢く、複数の型を同時に推論することもできるんです。これは、例えばタプル型(要素の型と数が決まった配列)や、より複雑な関数の引数・戻り値の型を扱いたい時に役立ちます。
例えば、タプル型から最初の要素の型だけを取り出す、なんてことも可能です。
// Tはタプル型を表す
// infer First は、タプルの最初の要素の型を推論する
// …Rest は、残りの要素の型をタプルとして推論する(ここでは使わないけど、こういうこともできる)
type GetFirstElement
// 例:名前(string)と年齢(number)のタプル
type PersonInfo = [string, number];
type NameType = GetFirstElement
`[infer First, …any[]]`という書き方がポイントです。これは「型が`First`と、その後に続く何らかの要素(`…any[]`)からなる配列(タプル)である」という条件を表しています。そして、`infer First`でその最初の要素の型を「First」という名前で取得しているわけです。
inferキーワード、まとめ!📝
さて、`infer`キーワードについて、少しイメージが掴めたでしょうか?
- `infer`はConditional Typesの中で使われる、型を推論するためのキーワードです。
- 「この型の中から、この部分の型を抜き出して、別の型として使いたい!」という時に、その「抜き出したい部分」を`infer`で指定して、名前をつけることができます。
- 関数の戻り値の型や、配列の要素の型など、様々な場面で活用できます。
- 単一の型だけでなく、複数の型を同時に推論することも可能です。
最初は「なんだか難しそう…」と感じるかもしれませんが、実際にコードを書いて動かしてみると、「なるほど!そういうことか!」と膝を打つ瞬間が必ず来ます。
今回ご紹介した`infer`は、TypeScriptの型システムをより深く理解し、より柔軟で強力なコードを書くための、まさに「魔法の杖」のような存在です。ぜひ、あなたの開発でもどんどん活用してみてくださいね!
もし、「ここはもうちょっと詳しく知りたいな」とか、「こんなケースではどうなるの?」といった疑問があれば、いつでも気軽に声をかけてください。あなたのTypeScriptの旅を、全力で応援します!😊

コメント