こんにちは!フロントエンドの現場を渡り歩いてきた、シニアアーキテクトの私です。
JavaScriptを書いていると、「お、この関数、色んなデータ型を受け取れるようにしたいな」「でも、返ってくるデータの型もうまく連動させたいな」って思う瞬間、ありませんか?
TypeScriptを導入するのが一番の近道ではあるけれど、「今のプロジェクトは純粋なJavaScript(JSDoc)でいきたいんだよな…」という現場もまだまだたくさんあります。そんなとき、JSDocの `@template` という秘密兵器を知っていると、コードの安全性が一気に跳ね上がります。
今回は、この `@template` を使ったジェネリクス(型の穴埋めパズルみたいなもの)について、難しい専門用語をできるだけ抜きにして、一緒に紐解いていきましょう!
—
1. そもそも「ジェネリクス」ってなに?(お弁当箱の例え)
いきなり「ジェネリクス」なんて難しい言葉が出てくると、頭がフリーズしちゃいますよね。でも、安心してください。すごくシンプルな概念です。
想像してみてください。あなたは今、「何を入れてもいい魔法のお弁当箱」を作っています。
- 月曜日は、おにぎりを入れます(中身は「おにぎり」)。
- 火曜日は、サンドイッチを入れます(中身は「サンドイッチ」)。
このお弁当箱自体は、中の食べ物が何であっても「フタを閉めて持ち運ぶ」という機能は変わりませんよね。
プログラムの世界でも同じです。「この関数は、文字列でも数字でも、どんなデータでも受け取れるようにしたい!だけど、受け取ったものと同じ種類のデータをそのまま返したい」というときに使うのが、ジェネリクス(型パラメータ)なんです。
JavaScriptのJSDocでは、この「何が来るか分からないけど、お揃いにしたい型」に名前をつけて、 `@template T` というラベルで管理してあげます。
—
2. 実際に見てみよう!@template の基本的な書き方
百聞は一見に如かず。まずはコードを見てみましょう。
「受け取った値を、そのままそっくりそのまま返す」という、ちょっと拍子抜けするくらいシンプルな関数を例にします。
/
- @template T
- @param {T} value – 何か好きなデータ
- @returns {T} 受け取ったデータと同じ型の値
/
function echo(value) {
return value;
}
// 使ってみる
const resultString = echo(“こんにちは!”); // エディタは「これは文字列だな」と理解する
const resultNumber = echo(42); // エディタは「これは数値だな」と理解する
ここで注目してほしいのが、最初の行にあるこの書き方です。
/
- @template T
/
この `@template T` は、エディタ(VS Codeなど)に対してこう宣言しています。
「おい、今から `T` という名前の『型のかわり(プレースホルダー)』を使うからな。この `T` が何に化けるかは、この関数を使う人が決めるから、よろしく!」
もし、この `@template T` を書き忘れてしまうと、エディタは「うーん、この `T` って一体なに?(Any型みたいなものかな…)」となってしまい、型チェックの恩恵を受けられなくなってしまいます。
—
3. 実務でよくあるつまずきポイントと「大丈夫だよ」のフォロー
初心者のころ、私もここで盛大につまずきました。
「あれ?ちゃんと型を書いたのに、エラーが出る…」「思った通りに補完が出てくれない…」
よくある原因と、その解決策をそっとシェアしますね。
つまずき①:型が `any` に逃げてしまう
「とりあえず動けばいいや」とJSDocをサボると、JavaScriptはすぐに何でも受け付ける `any`(何でもあり)の海に放り出します。そうすると、タイポ(入力ミス)をしてもエディタが教えてくれなくなります。
対策:
「あ、このデータ型は呼び出し元によって変わるな」と思ったら、迷わず関数の上に `@template T` を置いて、引数と戻り値に同じ `T` を使ってみてください。それだけで、エディタの賢さが何倍にも跳ね上がります。
つまずき②:複数の型を扱いたくなったら?
「データが2つあって、それぞれ違う型かもしれないときはどうするの?」
安心してください。`T` だけでなく、アルファベットの文字を変えて複数並べることもできます。
/
- 2つの異なるデータをペアにする関数
- @template T, U
- @param {T} first – 1つ目のデータ(型 T)
- @param {U} second – 2つ目のデータ(型 U)
- @returns {[T, U]} ふたつのデータをまとめた配列
/
function makePair(first, second) {
return [first, second];
}
// 1つ目は文字列、2つ目は数値のペアを作る
const pair = makePair(“年齢”, 25);
`@template T, U` と書くことで、「1つ目は `T` という型、2つ目は `U` という型だよ」と独立して教えることができます。お買い物かごに「りんご(T)」と「レシート(U)」を一緒にポンと入れるようなイメージですね。
—
4. 今日のまとめと、次のステップへ
今回は、JSDocの `@template` を使ったジェネリクスの表現についてお話しました。
- ジェネリクスとは:型をあとから自由にはめ込める「型のお弁当箱」。
- @template とは:エディタに「今からこの関数用の型の名前(ラベル)を定義するよ」と教える合言葉。
- メリット:純粋なJavaScriptのままで、コードの柔軟性と強力な型補完の両方を手に入れられる!
TypeScriptをいきなり導入するのはハードルが高い…と感じているWeb制作の現場や、ちょっとしたJavaScriptのツール開発であっても、このJSDocの `@template` さえ知っていれば、コードの品質は劇的に上がります。
「なんだか難しそう」と思っていた方も、まずは今日のサンプルコードを自分のエディタにコピペして、マウスカーソルを関数名に合わせてみてください。「おっ、型をちゃんと認識してくれている!」という小さな感動が、あなたのコーディングをもっと楽しくしてくれますよ。
それでは、また次の現場でお会いしましょう!あなたのJavaScriptライフが快適なものになりますように。

コメント