デフォルト引数は「来なかったときの標準値」
デフォルト引数は、「この引数が渡されなかったときは、代わりにこれを使ってね」という“標準値”をあらかじめ決めておく仕組みです。
書き方はシンプルで、引数に = で値をつけます。
function greet(name: string, title: string = "Mr.") {
console.log(`${title} ${name}`);
}
greet("Taro"); // "Mr. Taro"
greet("Taro", "Dr."); // "Dr. Taro"
TypeScriptここでは、第二引数 title に "Mr." というデフォルト値が設定されています。
呼び出し側が title を省略したとき、関数の中では title は自動的に "Mr." になります。
ポイントは、「呼び出し側は省略できるけど、関数の中では必ず string として扱える」ことです。
これはオプション引数(title?: string)との大きな違いです。
デフォルト引数とオプション引数の違い
オプション引数は「ないかもしれない」、デフォルト引数は「必ずある」
まずオプション引数の例から。
function greetOptional(name: string, title?: string) {
console.log(`${title} ${name}`); // エラーの可能性
}
TypeScripttitle?: string だと、「title は string かもしれないし、undefined かもしれない」という意味になります。
そのため、何もチェックせずに title を使おうとするとエラーになります。
function greetOptional(name: string, title?: string) {
if (title) {
console.log(`${title} ${name}`);
} else {
console.log(name);
}
}
TypeScript一方、デフォルト引数はこうです。
function greetDefault(name: string, title: string = "Mr.") {
console.log(`${title} ${name}`); // ここでは title は常に string
}
TypeScriptここでは、title の型は 純粋に string です。undefined にはなりません。必ず何かしらの文字列が入っています(渡されなければ "Mr.")。
整理すると、イメージはこうです。
オプション引数(title?: string)
→ 「渡されないかもしれない。中身は string | undefined」
デフォルト引数(title: string = "Mr.")
→ 「呼び出し側は省略できるが、中では必ず string」
「中で毎回 undefined チェックしたくない」「必ず値がある前提で書きたい」
そんなときに、デフォルト引数が威力を発揮します。
デフォルト引数が呼ばれるタイミング
「引数が省略されたとき」「undefined が渡されたとき」
デフォルト引数は、「何も渡されなかったとき」だけではなく、「undefined が渡されたとき」にも使われます。
function sample(value: number = 10) {
console.log(value);
}
sample(); // 10(省略 → デフォルト)
sample(5); // 5
sample(undefined); // 10(undefined → デフォルト適用)
sample(0); // 0
TypeScriptここでのポイントは、
sample() → 引数なし → デフォルトの 10sample(undefined) → 明示的に undefined → それでもデフォルトの 10sample(0) → 値あり → 0 をそのまま使う
という挙動です。
つまり、「undefined は“値がない”として扱われ、デフォルト値に置き換わる」と覚えておくとよいです。null を渡した場合はデフォルトは使われず、value はそのまま null になります。
デフォルト引数と型推論
デフォルト値から型が推論される
デフォルト値を指定すると、TypeScript はそこから引数の型を推論してくれます。
function mul(value = 1) {
return value * 2;
}
TypeScriptこの場合、value の型は自動的に number と推論されます。
戻り値も number になります。
もちろん、明示的に型を書くこともできます。
function mul(value: number = 1): number {
return value * 2;
}
TypeScript学習中や小さなスクリプトでは型推論に任せてもいいですが、
実務や共有コードでは、「引数型や戻り値型は積極的に明示した方が読みやすい」ことが多いです。
デフォルト引数の位置と順番
デフォルト引数は「後ろ側」に置く
オプション引数と同じく、デフォルト引数も基本は後ろ側に置くのが素直です。
function greet(name: string, title: string = "Mr.") {
console.log(`${title} ${name}`);
}
TypeScript実は、これは技術的には「前にデフォルト引数を置く」こともできますが、
呼び出し側が混乱しやすくなるので、実務では「必須 → デフォルト付き」の順番にするのが圧倒的に多いです。
// あまりやらない方がいい例
function weird(title: string = "Mr.", name: string) {
console.log(`${title} ${name}`);
}
TypeScriptこうすると、呼び出し時に必ず name は渡さないといけないのに、
第一引数に「title なのか name なのか」が分かりづらくなります。
実務での感覚としては、
「前のほうは必須引数」
「後ろのほうがオプション・デフォルト付き引数」
と覚えておくと、読み手にやさしい関数になります。
デフォルト引数とオブジェクト引数の組み合わせ
設定オブジェクトにデフォルトを入れる
少し実務寄りの典型パターンです。
「オプションが増えてきたらオブジェクトにまとめる」+「そのオブジェクト自体にデフォルトを入れる」パターン。
type GreetOptions = {
title?: string;
upperCase?: boolean;
};
function greet(name: string, options: GreetOptions = {}) {
const title = options.title ?? "Mr.";
const formattedName = options.upperCase ? name.toUpperCase() : name;
console.log(`${title} ${formattedName}`);
}
greet("Taro");
greet("Taro", { title: "Dr." });
greet("Taro", { upperCase: true });
greet("Taro", { title: "Prof.", upperCase: true });
TypeScriptここでは、
第二引数 options 自体に {} というデフォルト値を設定options を省略して呼んでも、関数内では必ずオブジェクトとして扱える
という状態になっています。
さらに、options.title ?? "Mr." で、
「title が undefined または存在しないときにだけ "Mr." を使う」というロジックを実現しています。
このパターンは実務でかなりよく出てきます。
「引数が多くなってきたら、オブジェクト + デフォルト引数」がとても読みやすい設計になります。
デフォルト引数を設計するときに考えてほしいこと
デフォルト引数は、ただの「便利機能」ではなく、設計の意思表示です。
この引数が省略されたとき、どんな振る舞いが「自然」か?
その省略時の振る舞いは、アプリ全体を通して一貫しているか?
そのデフォルト値は、時間が経っても変えたくならないか?
例えば、
function fetchUsers(limit: number = 20) {
// limit件だけユーザーを取ってくる
}
TypeScriptここでの 20 は、「このアプリでは、ユーザー一覧のデフォルト表示件数は 20」という仕様そのものです。
もしあとから「やっぱ 50 件にしよ」となると、ここを書き換えることになります。
だからこそ、デフォルト引数を書くときは、
「これはこの仕様の“標準設定”なんだ」と自覚して決めるのが大事です。
まとめ:デフォルト引数の本質的な役割
デフォルト引数は、ざっくり言えばこういうものです。
「この引数が来なかったときは、アプリとして“これを標準値とみなす”」
「呼び出し側には引数を省略する自由を与えつつ、関数の中では“必ず値がある世界”を作る」
その結果として、
呼び出し側のコードがスッキリし
関数の中では undefined チェックが減り
仕様上の“標準の振る舞い”が、コードにそのまま刻まれる
という状態が作れます。
オプション引数とセットで、こんな質問を自分に投げかけてみてください。
「この引数がないとき、“何もしない”のが自然なのか?」
「それとも、“この値が使われる”のが自然なのか?」
前者ならオプション引数(?)、
後者ならデフォルト引数(=)です。
その選び方そのものが、あなたの設計センスになっていきます。
