TypeScriptにおける関数
この記事ではTypeScriptにおける関数について説明します。
YouTube Video
TypeScriptにおける関数
TypeScriptにおける関数は、JavaScriptの関数に型注釈を加えたものです。TypeScriptでは、関数に入力(引数)や出力(戻り値)の型を明確に定義することで、より堅牢なコードを書くことができます。以下、基本的な関数の定義方法や、TypeScriptの関数の特徴をいくつか紹介します。
基本の関数定義
1function add(x: number, y: number): number {
2 return x + y;
3}
4
5console.log(add(5, 10)); // 15
- 関数
add
は、2つのnumber
型の引数を取り、number
型の値を返します。 x
とy
の2つの引数を受け取り、それぞれnumber
で、引数の型を指定しています。- 戻り値の型も
: number
で指定しています。
無名関数(関数式)
無名関数や関数式もTypeScriptでは使用できます。型は同じように注釈できます。
1const multiply = function (x: number, y: number): number {
2 return x * y;
3};
4
5console.log(multiply(3, 4)); // 12
- 無名関数を変数に代入し、呼び出すことができます。
1const factorial = function fact(n: number): number {
2 if (n <= 1) return 1;
3 return n * fact(n - 1); // Can call itself recursively
4};
5
6console.log(factorial(5)); // 120
- 名前付きの関数式を使うと再帰呼び出しができます。
アロー関数
アロー関数でも型注釈が可能です。
1const subtract = (x: number, y: number): number => {
2 return x - y;
3};
4
5console.log(subtract(10, 4)); // 6
このコードは、2つの数値を引数に取り、その差を返すアロー関数 subtract
を型注釈付きで定義しています。
オプション引数とデフォルト引数
引数を省略可能にしたり、デフォルト値を設定することもできます。
オプション引数
引数名の後に ?
をつけると、その引数は省略可能になります。
1function greet(name?: string): string {
2 return name ? `Hello, ${name}` : "Hello!";
3}
4
5console.log(greet()); // Hello!
6console.log(greet("Alice")); // Hello, Alice
このコードは、省略可能な引数を受け取り、引数が渡された場合はその名前を使って挨拶し、渡されない場合は一般的な挨拶を返します。
デフォルト引数
引数にデフォルト値を設定することもできます。
1function greetWithDefault(name: string = "Guest"): string {
2 return `Hello, ${name}`;
3}
4
5console.log(greetWithDefault()); // Hello, Guest
6console.log(greetWithDefault("Bob")); // Hello, Bob
この関数は、引数が渡されなかった場合に "Guest"
をデフォルト値として使用し、指定された名前またはデフォルトの名前で挨拶します。
関数の型定義
関数自体の型を定義することも可能です。例えば、引数として関数を渡す場合に使用します。
1type Operation = (x: number, y: number) => number;
2
3const addOperation: Operation = (x, y) => x + y;
4const multiplyOperation: Operation = (x, y) => x * y;
5
6console.log(addOperation(2, 3)); // 5
7console.log(multiplyOperation(2, 3)); // 6
このコードは、2つの数値を受け取り数値を返す関数型 Operation
を定義し、その型を使って加算と乗算の関数を作成し、実行しています。
戻り値がない場合(void
型)
戻り値がない関数には、void
型を指定します。
1function logMessage(message: string): void {
2 console.log(message);
3}
4
5logMessage("This is a message."); // This is a message.
このコードは、文字列メッセージを受け取ってコンソールに出力し、値を返さない void
型の関数 logMessage
を定義しています。
コールバック関数
関数を引数として他の関数に渡し、その関数が後で実行することをコールバック関数といいます。非同期処理やイベント処理で頻繁に使われます。
1function processData(callback: (data: string) => void): void {
2 const data: string = "Processed Data";
3 callback(data);
4}
5
6processData((result: string): void => {
7 console.log(result);
8});
この例では、コールバック関数としてコンソールに値を出力する関数を渡しています。
または、type
やinterface
を使ってコールバック型を定義することもできます。
1type Callback = (data: string) => void;
2
3function processData(callback: Callback): void {
4 const data: string = "Processed Data";
5 callback(data);
6}
7
8processData((result: string): void => {
9 console.log(result);
10});
type
やinterface
を使ってコールバック型を定義すると、再利用性が高くなります。
関数のオーバーロード
関数のオーバーロード(overloading)は、同じ関数名で異なる引数リストを持つ関数を定義できる機能です。TypeScriptでは、同じ名前の関数を複数定義し、引数の型や数によって異なる処理を行うことができます。
1// Overload Signature
2function double(value: number): number;
3function double(value: string): string;
4
5// Implementation Signature
6function double(value: number | string): number | string {
7 if (typeof value === "number") {
8 return value * 2;
9 } else if (typeof value === "string") {
10 return value + value;
11 }
12}
13
14console.log(double(10)); // 20
15console.log(double("Hello")); // HelloHello
TypeScriptでは、次のようにオーバーロードを実現します。
-
オーバーロードシグネチャ(Overload Signature)
- 関数の使い方(シグネチャ)を定義します。これが複数回書かれることで、オーバーロードが可能になります。
-
実装シグネチャ(Implementation Signature)
- 実際の関数本体を実装します。この部分は1つだけで、オーバーロードシグネチャで宣言されたすべてのケースに対応します。
オーバーロードのルール
関数のオーバーロードには、次のようなルールがあります。
-
オーバーロードシグネチャの定義順
- 上から順に評価されるため、具体的な型から汎用的な型の順に定義することが推奨されます。
-
実装シグネチャの互換性
- 実装シグネチャは、すべてのオーバーロードシグネチャの引数と戻り値に対応する必要があります。
-
オーバーロードシグネチャで詳細を指定
- 実装シグネチャは曖昧になりがちなので、オーバーロードシグネチャで詳細を指定します。
- 実装シグネチャだけを定義すると、関数の型推論が不十分になります。
まとめ
TypeScriptにおける関数には、次のような特徴があります。
- 型注釈
- 引数や戻り値に型を指定して、安全なコードを実現します。
- 無名関数・アロー関数
- JavaScriptと同様に使用可能で、型注釈を加えることで型安全性を向上させます。
- オプション引数・デフォルト引数
- 必要に応じて引数の指定を柔軟にすることができます。
- 関数の型定義
- 関数そのものの型を定義して、型チェックを行います。
- 関数のオーバーロード
- 同じ関数名で異なる引数をサポートできます。
これらを活用することで、より明確で堅牢なコードをTypeScriptで記述できます。
YouTubeチャンネルでは、Visual Studio Codeを用いて上記の記事を見ながら確認できます。 ぜひYouTubeチャンネルもご覧ください。