こんにちは!フロントエンド・アーキテクチャの現場を渡り歩いてきた、いわゆる「テックおじさん」です。
TypeScriptを触り始めると、型パズルみたいな機能がたくさん出てきて、最初は頭がクラクラしますよね。「なんだこれ、難しそう……」とそっとエディタを閉じたくなる気持ち、痛いほどよく分かります。私も昔は `any` ですべてを包み込んで夜中に冷や汗をかいていた口ですから。
さて、今回はそんなTypeScriptの数ある便利機能(ユーティリティ型)の中から、`Parameters
名前だけ聞くと「なんだか難しそうな数学の用語かな?」と思ってしまいますよね。でも大丈夫。身近な例えを交えながら、ゆっくり紐解いていけば「なーんだ、そういうことか!」とスッキリ腑に落ちるはずです。肩の力を抜いて、コーヒーでも飲みながら一緒に見ていきましょう。
—
1. `Parameters` って、そもそも何をするもの?
いきなりコードを書く前に、身近なもので例えてみましょう。
例えば、あなたが街の洋食屋さんで「特製ランチセット」を注文するとします。そのセットには、「メインのおかず」「スープ」「ライス」の3つが必ず決まった順番でついてきますよね。
この「特製ランチセット」というレシピ(関数)があったとき、「この料理を作るためには、具体的にどんな材料(引数)を、どんな順番(タプル)で用意すればいいんだっけ?」と、レシピから材料のリストを自動で抜き出してくれる魔法の道具。それが `Parameters
プログラムの世界で言うと、「ある関数が受け取る『引数の型たち』を、ひとまとめのタプル(配列のようなもの)として抽出する」ためのビルトイン(最初から用意されている)型なんです。
—
2. まずは基本の「き」:関数から引数の型を取り出してみる
百聞は一見にしかず。まずは実際にコードを書いてその動きを見てみましょう。
ここに、ユーザーのプロフィールを登録する関数があるとします。
// ユーザー登録をする関数
function registerUser(name: string, age: number, isPremium: boolean) {
console.log(`${name}さん(${age}歳)を登録しました。`);
}
この関数 `registerUser` は、文字列(`string`)、数値(`number`)、真偽値(`boolean`)という3つの引数を受け取りますよね。
もし、「この `registerUser` 関数が受け取る引数の型だけを、別の場所でも使い回したい!」と思ったとき、どう書くでしょうか? まさか手動で `[string, number, boolean]` なんて書き直しませんよね。そんなことをしたら、将来的に関数の引数を増やしたときに、型の修正漏れが起きてバグの温床になってしまいます。
そこで `Parameters
// registerUser関数の引数の型をまるっと抽出して、新しい型を作る!
type RegisterUserParams = Parameters
// この時、RegisterUserParams は自動的に以下の型と同じ意味になります。
// [name: string, age: number, isPremium: boolean]
おおっ、どうでしょう?
`typeof registerUser` で「この関数の型だよ」と指定し、それを `Parameters<...>` で包むだけで、引数の型たちがきれいなタプル(順番がカチッと決まった配列)になって手に入りました。
—
3. なぜこれが実務で役に立つの?(具体的なシチュエーション)
「ふーん、引数の型を取り出せるのは分かったけど、それの何がそんなに凄いの?」と思われるかもしれません。
実はこれ、「すでにある外部のライブラリの関数」や「自分で書いたけど引数がやたらと多い関数」の型を安全に扱いたいときに、もの凄く真価を発揮します。
例えば、実務でよくあるのが「関数の実行をちょっと遅らせたい(デバウンス処理)」とか「関数の引数をそのまま別の関数にパスしたい(ラッパー関数)」というケースです。
ちょっと次のコードを見てください。
// 外部のAPIを叩く、ちょっと複雑な関数だと想像してください
function fetchUserData(userId: string, includeDetails: boolean, retryCount: number) {
// 通信処理…
}
// この関数の実行を安全にラップ(包み込む)する関数を作りたい!
// 引数の型を手動で書くのは面倒だし、元が変わったときに追いつかなくなる…
ここで `Parameters
// 元の関数の引数の型をそのまま流用するラッパー関数
function safeFetchUser(…args: Parameters
console.log(“通信を開始する前にログを記録します!”);
// スプレッド構文 (…) でそのまま元の関数に引数をパスする
return fetchUserData(…args);
}
見てください、このスッキリとした美しさを!
`safeFetchUser` の引数の部分に `…args: Parameters
もし将来、元の `fetchUserData` に新しい引数(例えば `timeout: number`)が追加されたとしても、ラッパー側の型を手動で書き直す必要はありません。TypeScriptが自動で「あ、引数が変わったんだね」と検知して、すべてを辻褄フレンズとして守ってくれます。最高ですね。
—
4. 初学者がつまずきやすいポイントと「大丈夫ですよ」のフォロー
ここで、よくある「うっかりミス」と、その処方箋をシェアしておきますね。
つまずきポイント:値(関数そのもの)をそのまま渡そうとして怒られる
`Parameters` は、あくまで「型の世界(Type)」で動く仕組みです。そのため、関数の中身(値)を直接渡そうとすると、TypeScriptくんに「それ、値でああって型じゃないよ!」と怒られてしまいます。
// ❌ やりがちな間違い
type BadParams = Parameters
// エラー:「’registerUser’ は値ですが、ここでは型として使用されています。」
【解決のコツ】
関数から型を取り出したいときは、必ず `typeof` をセットで使いましょう!
// ⭕️ 正しい書き方
type GoodParams = Parameters
「`typeof` をつけることで、関数の実体を『関数の型』という設計図に変換しているんだな」とイメージしてくださいね。最初は忘れがちですが、何度も書いていれば自然と手が覚えていきますよ。
—
おわりに
今回は、TypeScriptの `Parameters
- `Parameters
` とは? :関数がどんな引数を求めているのか、そのレシピ(タプル)を自動で抽出してくれる便利な道具。 - いつ使うの?:既存の関数の引数の型を使い回したいときや、ラッパー関数を作るときにコードの重複とメンテナンスの手間を減らしてくれる。
- 注意点は?:関数から型を取り出すときは `typeof` を忘れずに!
型定義の世界は、最初は少し冷たく感じるかもしれませんが、使いこなせるようになると「自分の書いたコードを強力に守ってくれる頼もしい相棒」に変わります。
もし今日のエントリで「ここはこういうこと?」と疑問に思ったことがあれば、ぜひご自身の環境でエディタを開いて、色々な関数を `Parameters
それでは、また次のTypeScriptの深掘り記事でお会いしましょう!快適な型ライフを!

コメント