TypeScriptにおける関数

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 型の値を返します。
  • xyの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});

この例では、コールバック関数としてコンソールに値を出力する関数を渡しています。

または、typeinterfaceを使ってコールバック型を定義することもできます。

 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});

typeinterfaceを使ってコールバック型を定義すると、再利用性が高くなります。

関数のオーバーロード

関数のオーバーロード(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チャンネルもご覧ください。

YouTube Video