こんにちは、かつコーチです。
プログラミングにおいて関数はとても重要な項目です。
TypeScriptでは、関数の作成方法や型定義について強力な機能が提供されており、
型安全なコードを書くことができます。
ここでは、関数の基本的な作成方法から、関数の型注釈、戻り値の型、オプショナル引数、
デフォルト引数、レストパラメータ、無名関数やコールバック関数、
アロー関数、ジェネリクスを用いた関数について詳しく解説します。
基本的な関数の作り方
TypeScriptでは、関数をJavaScriptと同様に定義しますが、
引数や戻り値に型注釈をつけることができ、型安全なコードを書くことが可能です。
関数宣言
function greet(name: string): string {
return `Hello, ${name}!`;
}
console.log(greet("Alice")); // "Hello, Alice!"
name: string
は引数name
が文字列型であることを指定しています。: string
はこの関数の戻り値が文字列型であることを表します。
関数式
関数を変数に代入する形式でも定義できます。
この方法は、関数を他の変数のように扱うことが可能です。
const greet = function (name: string): string {
return `Hello, ${name}!`;
};
console.log(greet("Bob")); // "Hello, Bob!"
関数の型注釈
関数の引数と戻り値に対して、明示的に型を指定することができます。
これにより、予期しない型の引数や戻り値を防ぐことができます。
複数の引数を持つ関数
function add(x: number, y: number): number {
return x + y;
}
console.log(add(5, 3)); // 8
この関数add
は、2つの数値x
とy
を引数として取り、それらを加算した結果(数値)を返します。
戻り値がない関数
戻り値がない場合、TypeScriptでは型void
を指定します。
これは、関数が値を返さないことを示す型です。
function logMessage(message: string): void {
console.log(message);
}
logMessage("This is a log message"); // "This is a log message"
オプショナル引数
関数の引数をオプションとして指定することもできます。
オプショナル引数は、引数名の後に?
をつけて定義します。
function greet(name: string, greeting?: string): string {
return greeting ? `${greeting}, ${name}!` : `Hello, ${name}!`;
}
console.log(greet("Alice")); // "Hello, Alice!"
console.log(greet("Alice", "Good morning")); // "Good morning, Alice!"
この例では、greeting
引数はオプションであり、
指定しなかった場合には"Hello"
がデフォルトの挨拶になります。
デフォルト引数
引数にデフォルト値を指定することができ、
関数呼び出し時に引数が省略された場合、そのデフォルト値が使われます。
function greet(name: string, greeting: string = "Hello"): string {
return `${greeting}, ${name}!`;
}
console.log(greet("Alice")); // "Hello, Alice!"
console.log(greet("Alice", "Hi")); // "Hi, Alice!"
この例では、greeting
引数にデフォルトで"Hello"
が指定されています。
レストパラメータ
レストパラメータを使うと、可変長引数を扱うことができます。
関数が任意の数の引数を受け取れるようにするため、...
を使います。
function sum(...numbers: number[]): number {
return numbers.reduce((total, num) => total + num, 0);
}
console.log(sum(1, 2, 3, 4)); // 10
console.log(sum(5, 10)); // 15
この例では、sum
関数は任意の数の数値を引数として受け取り、その合計を返します。
無名関数(匿名関数)
無名関数は、名前を持たない関数です。
コールバック関数や即時関数などでよく使われます。
コールバック関数
function processInput(input: string, callback: (output: string) => void): void {
const result = input.toUpperCase();
callback(result);
}
processInput("hello", (output) => {
console.log(output); // "HELLO"
});
コールバック関数として、無名関数を引数に渡すことができます。
即時実行関数
即時実行関数(IIFE)は、定義と同時に実行される無名関数です。
(function () {
console.log("This is an IIFE");
})(); // "This is an IIFE"
アロー関数
アロー関数(Arrow Function)は、短く記述できる関数です。無名関数の代わりに使われることが多く、this
の扱いが従来の関数と異なります。アロー関数は、関数本体内でthis
が常に外側のスコープを参照します。
const greet = (name: string): string => `Hello, ${name}!`;
console.log(greet("Alice")); // "Hello, Alice!"
関数のオーバーロード
TypeScriptでは、同じ名前の関数に対して異なるシグネチャ(型定義)を持たせることができます。これを関数のオーバーロードと呼びます。
function double(value: string): string;
function double(value: number): number;
function double(value: any): any {
if (typeof value === "number") {
return value * 2;
} else if (typeof value === "string") {
return value.repeat(2);
}
}
console.log(double(10)); // 20
console.log(double("abc")); // "abcabc"
この例では、数値と文字列の両方に対応するdouble
関数をオーバーロードしています。
ジェネリクスを使った関数
ジェネリクス(Generics)を使うことで、特定の型に依存しない汎用的な関数を定義できます。
ジェネリック関数は型引数を受け取ることで、異なる型に対して同じロジックを適用できます。
function identity<T>(arg: T): T {
return arg;
}
console.log(identity<string>("Hello")); // "Hello"
console.log(identity<number>(42)); // 42
この例では、identity
関数は型引数T
を取り、引数と戻り値の型を柔軟に変更できます。
まとめ
TypeScriptにおける関数の作成方法や使い方には、さまざまな柔軟性があります。
引数や戻り値に型注釈を付けることで、関数の動作をより厳密に制御でき、
オプショナル引数やデフォルト引数、レストパラメータを活用することで、
柔軟かつ効率的な関数を作成できます。
さらに、アロー関数やジェネリクスを使うことで、
モダンで再利用性の高いコードを書くことができます。