TypeScriptは、静的型付けによってJavaScriptの開発体験を劇的に向上させる言語として、2026年現在も開発現場で標準的に採用されています。
その中でも「デフォルト引数」は、関数の柔軟性を高めつつ、コードの冗長さを抑えるために非常に重要な役割を担っています。
適切にデフォルト引数を活用することで、呼び出し側の負担を減らし、型の恩恵を最大限に受けることが可能になります。
本記事では、TypeScriptにおけるデフォルト引数の基礎から、実践的な型定義の応用テクニックまでを詳しく解説します。
TypeScriptにおけるデフォルト引数の役割
デフォルト引数とは、関数を呼び出す際に引数が渡されなかった場合に、あらかじめ指定した値が自動的に代入される仕組みです。
JavaScriptの標準機能であるこの仕組みを、TypeScriptでは強力な型システムと組み合わせて利用することができます。
デフォルト引数を活用することで、過剰なオーバーロードを避けることができ、シンプルでメンテナンス性の高い関数設計が実現します。
基本的な記述方法
TypeScriptでデフォルト引数を定義するには、引数名の後に = を用いて値を記述します。
以下の例では、message 引数に対してデフォルト値を設定しています。
function displayAlert(message: string = "システムエラーが発生しました"): void {
// 引数が渡されない場合はデフォルトの文字列が表示される
console.log(message);
}
displayAlert(); // デフォルト値が使用される
displayAlert("接続に成功しました"); // 指定した値が使用される
"システムエラーが発生しました"
"接続に成功しました"
このように、デフォルト値を設定することで、関数呼び出し時に引数を省略することが可能になります。
デフォルト引数と省略可能引数の違い
TypeScriptには、引数を任意にするための「省略可能引数(?)」という機能も存在します。
デフォルト引数を使用する場合、その引数は暗黙的に「省略可能」として扱われるため、別途 ? を付ける必要はありません。
省略可能引数では値が渡されない場合に undefined となりますが、デフォルト引数では指定した値が確実に入る点が大きな違いです。
| 機能 | 記述例 | 値が未指定時の挙動 |
|---|---|---|
| デフォルト引数 | arg: string = "default" | 指定した値(”default”)が代入される |
| 省略可能引数 | arg?: string | undefined が代入される |
実行時の安全性を考慮すると、undefined のチェックが不要になるデフォルト引数の方が、堅牢なコードを書きやすくなります。
型推論と明示的な型定義
TypeScriptの優れた点の一つは、デフォルト値から型を自動的に推論できることです。
多くの場合、デフォルト値を設定すれば明示的な型注釈を省略しても、TypeScriptが型を特定してくれます。
推論を活用した簡潔なコード作成
以下のコードでは、数値型のデフォルト値を設定することで、型推論が働いています。
// 型注釈を省略しても、TypeScriptはcountをnumber型と認識する
function increment(count = 0) {
return count + 1;
}
// 文字列を渡そうとするとコンパイルエラーになる
// increment("1");
型推論を最大限に活用することで、コードの可読性を保ちつつ、型安全性を確保することができます。
ただし、より複雑なオブジェクトや共用型を扱う場合には、明示的な型定義が必要になることもあります。
共用型(Union Types)との組み合わせ
特定の文字列のみを許可したい場合などは、リテラル型や共用型を明示的に指定するのが一般的です。
type Theme = "light" | "dark" | "system";
function applyTheme(theme: Theme = "system"): void {
console.log(`現在のテーマ: ${theme}`);
}
applyTheme(); // "system"
applyTheme("dark"); // "dark"
このように定義することで、デフォルト値を設定しつつ、許可されていない値が渡されるのを防ぐことができます。
オブジェクトの分割代入とデフォルト引数の高度な活用
関数の引数にオブジェクトを受け取る場合、分割代入とデフォルト引数を組み合わせると非常に強力です。
この手法は、Webアプリケーションの設定値や、ReactのProps管理などで頻繁に利用されます。
インターフェースを利用した定義
引数のオブジェクトに型定義を行い、さらにデフォルト値を設定する手法を確認しましょう。
interface Config {
url: string;
method?: "GET" | "POST";
timeout?: number;
}
function request({ url, method = "GET", timeout = 5000 }: Config): void {
console.log(`${method}リクエストを${url}に送信します。タイムアウトは${timeout}msです。`);
}
request({ url: "https://api.example.com" });
"GETリクエストをhttps://api.example.comに送信します。タイムアウトは5000msです。"
この記述により、method や timeout が省略された場合でも、関数内部ではデフォルト値が適用されます。
さらに、オブジェクト自体が渡されなかった場合のデフォルト値を設定することも可能です。
function initialize({ mode = "production" } = {}): void {
console.log(`モード: ${mode}`);
}
initialize(); // オブジェクト自体を省略可能
= {} という記述を加えることで、引数なしで initialize() を呼び出せるようになり、利便性が向上します。
実践的なユースケースと注意点
デフォルト引数を使用する際には、設計上のルールや挙動の特性を理解しておく必要があります。
特に引数の順番や、JavaScript特有の null と undefined の扱いの違いは重要です。
引数の順番と設計
デフォルト引数は、通常引数リストの最後に配置するのがベストプラクティスです。
もし最初の引数にデフォルト値を設定した場合、それをスキップして第2引数を渡すには、明示的に undefined を渡す必要があります。
function setup(port = 8080, host: string): void {
console.log(`Server running at ${host}:${port}`);
}
// 最初の引数をデフォルトのままにしたい場合
setup(undefined, "localhost");
このような呼び出し方は可読性を下げるため、デフォルト値を持つ引数は後ろにまとめるように設計しましょう。
nullとundefinedの挙動の違い
デフォルト引数が適用されるのは、引数が渡されなかった場合、または「undefined」が渡された場合のみです。
null が渡された場合はデフォルト値が適用されず、そのまま null として扱われる点に注意が必要です。
function greet(name: string = "名無しさん"): void {
console.log(`こんにちは、${name}`);
}
greet(undefined); // "こんにちは、名無しさん"
// greet(null); // 型エラー、またはデフォルト値は適用されない
この挙動はJavaScriptの仕様に基づいています。
TypeScriptでは、string 型の引数に null を渡すと型チェックでエラーが出るため、不用意なバグを防ぐことができます。
まとめ
TypeScriptのデフォルト引数は、コードをクリーンかつ安全に保つための強力な機能です。
基本的な構文を理解するだけでなく、型推論や分割代入と組み合わせることで、開発効率を大幅に高めることができます。
今回解説したポイントをまとめます。
- デフォルト引数は
= valueの形式で定義し、型の安全性と簡潔さを両立できる。 - 省略可能引数(
?)とは異なり、未指定時に特定の値を保証するため、実行時のエラーを防ぎやすい。 - オブジェクトの分割代入と組み合わせることで、複雑な関数のインターフェースを整理できる。
- デフォルト引数は原則として引数リストの最後に配置し、
undefined時にのみ適用されることを理解しておく。
2026年以降のモダンな開発においても、TypeScriptの機能を正しく使い分けることは、チーム開発における共通言語として不可欠です。
デフォルト引数を使いこなし、読みやすく堅牢なプログラムを作成していきましょう。
