関数の引数型って何をしているのか
まず一番シンプルに言うと、「この関数は、どんな“形”の値を受け取るのかを約束する」のが引数型です。
function add(a: number, b: number): number {
return a + b;
}
TypeScriptここで a: number と b: number が「引数の型」です。
「add は、number 型を2つ受け取る関数ですよ」と宣言しているわけです。
この「約束」を書いておくことで、
- 間違った型の値を渡そうとしたときにコンパイルエラーになる
- 関数の使い方が、型を見るだけで分かる
という状態になります。
引数型の基本的な書き方
1つの引数に型を付ける
function greet(name: string): void {
console.log(`Hello, ${name}`);
}
greet("Taro"); // OK
// greet(123); // エラー: number は string に渡せない
TypeScriptname: string の部分が、「この引数は string 型でなければならない」という宣言です。
型を書かなかった場合、引数は any とみなされてしまうので、TypeScript の恩恵がほぼ消えます。
複数引数の型
function createUser(name: string, age: number): { name: string; age: number } {
return { name, age };
}
createUser("Taro", 20); // OK
// createUser("Taro", "20"); // エラー
TypeScriptそれぞれの引数に対して、名前: 型 の形で書いていきます。
「引数ごとに型を付ける」のが基本形です。
TypeScript は「引数の数」もチェックする
JavaScript との大きな違い
JavaScript では、引数の数が合っていなくても普通に実行されます。
function increment(n) {
return n + 1;
}
increment(1, 2); // 余分な引数は無視される
increment(); // n は undefined になり、NaN になることも
TypeScriptTypeScript はここを厳密にチェックします。
function increment(n: number): number {
return n + 1;
}
increment(1); // OK
// increment(); // エラー: Expected 1 arguments, but got 0.
// increment(1, 2); // エラー: Expected 1 arguments, but got 2.
TypeScriptエラーメッセージの
Expected 1 arguments, but got 2.
は、「1個の引数を期待しているのに、2個渡されているよ」という意味です。
「数も型も合っているときだけ呼べる」というのが、TypeScript の関数呼び出しです。
オブジェクトを引数にする場合の型
オブジェクト引数に型を付ける
type User = {
name: string;
age: number;
};
function printUser(user: User): void {
console.log(`${user.name} (${user.age})`);
}
printUser({ name: "Taro", age: 20 }); // OK
// printUser({ name: "Taro" }); // エラー: age が足りない
TypeScriptここでは、user: User として「User 型のオブジェクト」を引数に受け取っています。
User 型の定義に従って、プロパティの有無や型がチェックされます。
分割代入と組み合わせる
function printUser2({ name, age }: User): void {
console.log(`${name} (${age})`);
}
TypeScript({ name, age }: User) は、
「User 型のオブジェクトを受け取り、その中から name と age を取り出す」という意味です。
「引数の形」と「中身の型」を同時に表現できる」ので、実務でもよく使われます。
配列を引数にする場合の型
配列全体を受け取る
function sum(numbers: number[]): number {
return numbers.reduce((acc, n) => acc + n, 0);
}
sum([1, 2, 3]); // OK
// sum(["1", "2"]); // エラー: string[] は number[] に渡せない
TypeScriptnumbers: number[] は、「number の配列」を受け取るという意味です。
配列の中身の型も、ちゃんとチェックされます。
配列の要素をオブジェクトにする
type Product = {
name: string;
price: number;
};
function total(products: Product[]): number {
return products.reduce((sum, p) => sum + p.price, 0);
}
TypeScriptここでは、「Product 型の配列」を受け取っています。
「配列の形」と「要素の形」を両方型で表現できる」のがポイントです。
optional 引数・デフォルト引数・rest 引数の型
optional 引数(あってもなくてもいい)
function greet(name: string, title?: string): void {
if (title) {
console.log(`${title} ${name}`);
} else {
console.log(name);
}
}
greet("Taro"); // OK
greet("Taro", "Dr."); // OK
TypeScripttitle?: string は、「この引数は省略してもよい」という意味です。
型としては string | undefined に近いイメージになります。
デフォルト引数
function greet2(name: string, title: string = "Mr."): void {
console.log(`${title} ${name}`);
}
greet2("Taro"); // "Mr. Taro"
greet2("Taro", "Dr."); // "Dr. Taro"
TypeScriptデフォルト値を指定すると、その型が自動的に引数型として推論されます。title は string として扱われます。
可変長引数(rest 引数)
function sumAll(...numbers: number[]): number {
return numbers.reduce((acc, n) => acc + n, 0);
}
sumAll(1, 2, 3); // OK
sumAll(10, 20); // OK
// sumAll(1, "2"); // エラー
TypeScript...numbers: number[] は、「number をいくつでも受け取る」という意味です。
「何個来るか分からないけど、全部同じ型」というときに使います。
「引数型」をどう意識すると上達が早いか
一番大事なのは、「この関数は、どんな値を受け取る“つもり”なのかを、型で正直に書く」という意識です。
「ここは絶対に string じゃないと困る」なら string と書く。
「ここは省略されることもある」なら ? を付ける。
「オブジェクトの形が決まっている」なら、型(type / interface)を定義してそれを使う。
そうすると、TypeScript がこういうことを全部チェックしてくれます。
- 引数の数が合っているか
- 引数の型が合っているか
- オブジェクトのプロパティが足りているか・余計なものがないか
関数を書くたびに、こう自分に問いかけてみてください。
「この関数は、本当はどんな“形”のデータを受け取りたいんだっけ?」
その答えを、引数型として素直に書いていく——
それが、関数の引数型を“使いこなす”ための一番の近道です。

