TypeScriptのオプショナル引数(?)とrest引数(...)の使い方を徹底解説!初心者でもわかる関数パラメータの基本
生徒
「TypeScriptで関数の引数を柔軟に設定する方法ってありますか?」
先生
「はい。TypeScriptでは『オプショナル引数』と『rest引数』という方法を使えば、引数の数や使い方を自由に調整できますよ。」
生徒
「それって具体的にどういうときに使うんですか?」
先生
「例えば、ある引数はあってもなくてもよかったり、逆に何個渡しても受け取れるようにしたい場合ですね。では、順番に説明していきましょう!」
1. オプショナル引数(?)とは?
TypeScriptのオプショナル引数とは、関数の引数があってもなくても良い場合に使える書き方です。引数名のあとに「?」を付けるだけで、その引数を省略できるようになります。
例えば、「名前」は必ず必要だけど、「年齢」は入力してもしなくても良い、という関数を作りたい場合に便利です。オプショナル引数が省略された場合、その値は自動的にundefined(値がない状態)になります。
function greet(name: string, age?: number) {
if (age !== undefined) {
console.log(`こんにちは、${name}さん。年齢は${age}歳ですね。`);
} else {
console.log(`こんにちは、${name}さん。`);
}
}
greet("太郎", 25); // 年齢あり
greet("花子"); // 年齢なし
実行結果:
こんにちは、太郎さん。年齢は25歳ですね。
こんにちは、花子さん。
このように、オプショナル引数は入力を省略できるため、関数の柔軟性が上がります。
2. rest引数(...)とは?
TypeScriptのrest引数は、引数をまとめて配列として受け取るための仕組みです。書き方は引数名の前に「...」を付けます。これを使うと、「何個渡してもOK」な関数が作れます。
例えば、複数の数値を渡して合計を計算する関数を作ってみましょう。
function sum(...numbers: number[]) {
let total = 0;
for (let num of numbers) {
total += num;
}
console.log(`合計は${total}です。`);
}
sum(1, 2, 3); // 3つの引数
sum(5, 10, 15, 20); // 4つの引数
sum(); // 引数なし
実行結果:
合計は6です。
合計は50です。
合計は0です。
このように、rest引数を使うと、引数の数に制限がなくなります。
3. オプショナル引数とrest引数を組み合わせる
実は、オプショナル引数とrest引数は同じ関数内で組み合わせて使うこともできます。ただし、TypeScriptではrest引数は必ず最後に書く必要があるというルールがあります。
例えば、最初の引数は必須、2つ目の引数はオプショナル、それ以降はすべてまとめて受け取る、という関数を作ることが可能です。
function info(name: string, age?: number, ...hobbies: string[]) {
console.log(`名前: ${name}`);
if (age !== undefined) {
console.log(`年齢: ${age}`);
}
if (hobbies.length > 0) {
console.log(`趣味: ${hobbies.join("、")}`);
}
}
info("太郎", 25, "読書", "旅行");
info("花子", undefined, "音楽", "映画", "料理");
実行結果:
名前: 太郎
年齢: 25
趣味: 読書、旅行
名前: 花子
趣味: 音楽、映画、料理
このように、組み合わせることで引数の受け取り方をさらに自由にできます。
4. オプショナル引数とデフォルト値の違い
オプショナル引数と似ている機能にデフォルト引数があります。デフォルト引数は、省略された場合にあらかじめ決めた値を自動的に使う仕組みです。
例えば、年齢を省略したら自動的に20歳とみなす場合はこう書きます。
function greetWithDefault(name: string, age: number = 20) {
console.log(`こんにちは、${name}さん。年齢は${age}歳ですね。`);
}
greetWithDefault("太郎", 25); // 年齢あり
greetWithDefault("花子"); // 年齢なし(デフォルト適用)
実行結果:
こんにちは、太郎さん。年齢は25歳ですね。
こんにちは、花子さん。年齢は20歳ですね。
つまり、オプショナル引数は「値がないことも許可する」機能、デフォルト引数は「値がない場合に決まった値を使う」機能です。
5. 初心者がつまずきやすいポイント
- オプショナル引数(
?)は必須引数の後に書く必要がある - rest引数(
...)は必ず引数リストの最後に置く - オプショナル引数を省略すると、その値は
undefinedになる - rest引数は配列として受け取れるので、
for...ofやmapが使える
まとめ
TypeScriptのオプショナル引数とrest引数について学んできましたが、あらためて振り返ってみると、この二つの機能が関数を柔軟に扱ううえでどれほど役に立つかがよく理解できます。特に、オプショナル引数は「引数があってもなくても動く」関数を自然な形で書けるため、実際の開発では非常によく使われます。たとえば、ユーザー情報の一部だけが入力されていたり、あとから追加される可能性があるパラメータに対応する場面など、現実のプログラムでは「値があるかもしれないし、ないかもしれない」という状況が頻繁にあります。そんなとき、毎回条件分岐で無理に処理を書き換える必要がなく、引数に「?」を付けるだけで省略可能にできるのは、TypeScriptの大きな魅力だといえます。 さらに、rest引数についても深く理解しておくと、多くの引数を扱う関数をすっきり書けるようになります。引数の数が毎回変わったり、場合によっては何十個にもなる処理を扱うときに、rest引数はとても頼りになる存在です。ひとつの配列にまとめて受け取ることで、for文やmapを使った繰り返し処理が自然に書けるようになり、コード全体が読みやすく整理された形になります。複数の値を扱う関数では、引数の順番や数が一定でないことも多く、その柔軟性を活かせる場面は日常的に多いはずです。 そして、オプショナル引数とrest引数は、ただ便利な記法というだけでなく、関数設計の幅そのものを広げてくれます。両者を組み合わせることで、「最初の引数は必ず必要」「二つ目はあってもなくてもよい」「三つ目以降は全部まとめて受け取りたい」というような複雑な関数の形を、無理のない自然な文法で表現できるようになります。この組み合わせは実際のアプリケーション開発でも多く使われ、特にユーザー入力の処理やイベントの管理など、状況によって渡されるデータが前後する場面で真価を発揮します。 また、デフォルト引数との違いを理解することで、関数に求められる動作をより正確にコントロールできるようになります。単に「値がなくてもよい」のか、それとも「値がなかったときは特定の初期値を使ってほしい」のか。この違いは一見すると小さく感じますが、プログラムの動作やユーザー体験に少しずつ影響を与える重要なポイントです。こうした考え方に慣れていくことで、TypeScriptの型システムが持つメリットも自然と理解できるようになり、結果としてエラーを減らしながら読みやすいコードを書く力が身についていきます。 何より、今回の内容を通して、関数パラメータの設計がプログラミングにおいて意外と重要な位置を占めていることに気づいた方も多いのではないでしょうか。引数をどう受け取り、どう扱うかは、アプリケーション全体の書きやすさや拡張しやすさに直結します。最初のうちは難しく感じるかもしれませんが、少しずつ使いながら慣れていけば、自然に自分の書くコードが整理され、見通しのよい形に整っていくはずです。関数の形を自由に変えられるということは、それだけ自分のアイデアを柔軟に表現できるということでもあり、これから学ぶさまざまな文法の中でも特に習得しておきたい知識です。 これらの知識を踏まえて、実際に手を動かしながら試してみることが一番効果的です。オプショナル引数とrest引数を混ぜたり、デフォルト値を設定したり、配列として受け取った値を加工したり、さまざまなパターンを自分で書いてみることで、より自然に理解が深まります。小さな例でもいいので、いくつかバリエーションを考えて試してみましょう。そうすることで、TypeScriptという言語の柔軟さや設計のしやすさをより実感できるはずです。
サンプルコードで振り返り
function report(title: string, detail?: string, ...tags: string[]) {
console.log(`タイトル: ${title}`);
if (detail) {
console.log(`詳細: ${detail}`);
}
if (tags.length > 0) {
console.log(`タグ: ${tags.join("、")}`);
}
}
report("作業報告", "進捗良好", "TypeScript", "関数", "引数");
生徒
「オプショナル引数とrest引数の違いがわかりました。特に、どんな場面で使うのかがイメージしやすくなりました。」
先生
「実際の開発でもよく使われるので、今日学んだ内容はとても役に立ちますよ。使い方を身につけておくと、関数設計がぐっと楽になります。」
生徒
「rest引数で配列としてまとめて受け取れるのはすごく便利ですね。可変引数の処理がしやすくなるのを実感しました。」
先生
「そのとおりです。複数のデータを受け取る関数では欠かせない機能ですし、TypeScriptでは特に使いやすい形になっています。」
生徒
「これから関数を作るときに自然に使えるようになりたいです!」
先生
「ぜひ実際にどんどん書いてみてくださいね。手を動かすほど理解が深まりますよ。」