課題4: TypeScriptの関数 (発展) (所要時間目安: 20‐30分) - hideki5123/myts GitHub Wiki
次は、TypeScriptの関数について、もう少し掘り下げてみましょう。関数自体の型定義や、多様なパラメータの扱い方を見ていきます。
C#との比較:
- 関数型エイリアス (
type FuncType = ...
):- TypeScript: 関数のシグネチャ(引数の型と戻り値の型)を
type
エイリアスで定義できます。例:type MathOperation = (x: number, y: number) => number;
- C#: C#の
delegate
キーワード (delegate int MathOperation(int x, int y);
) や、より一般的にはSystem.Func
やSystem.Action
デリゲート (Func<int, int, int>
) に相当します。どちらも関数の型シグネチャを定義する方法です。
- TypeScript: 関数のシグネチャ(引数の型と戻り値の型)を
- オプショナルパラメータ (
param?: type
):- TypeScript: パラメータ名の後ろに
?
を付けると、そのパラメータが省略可能になります。オプショナルパラメータは必須パラメータの後ろに置く必要があります。例:function greet(name: string, title?: string)
- C#: C# 4.0以降のオプショナル引数と非常に似ています。C#では型名の後に
?
ではなく、パラメータにデフォルト値を指定する形 (string title = null
) やOptionalAttribute
を使いますが、呼び出し側で省略できる点は同じです。TypeScript同様、通常は必須引数の後に置きます。
- TypeScript: パラメータ名の後ろに
- デフォルトパラメータ (
param: type = value
):- TypeScript: パラメータにデフォルト値を指定できます。呼び出し時に引数が省略されると、このデフォルト値が使われます。例:
function power(base: number, exponent: number = 2)
- C#: C# 4.0以降のデフォルト引数 (
int exponent = 2
) と完全に同じ概念です。
- TypeScript: パラメータにデフォルト値を指定できます。呼び出し時に引数が省略されると、このデフォルト値が使われます。例:
- Restパラメータ (
...param: type[]
):- TypeScript: 関数の最後のパラメータとして、
...
を使うことで可変長の引数を受け取ることができます。受け取った引数は配列として扱われます。例:function sumAll(...numbers: number[]): number
- C#: C#の
params
キーワード (params int[] numbers
) と同じ目的を果たします。可変長の引数を配列として受け取る機能ですが、構文が異なります。
- TypeScript: 関数の最後のパラメータとして、
課題内容:
-
新しいファイルの作成:
src
ディレクトリにfunctions.ts
という新しいファイルを作成してください。 -
様々な関数の定義:
functions.ts
に以下のような関数を定義してみてください。// src/functions.ts // --- 1. 関数型エイリアス --- type MathOperation = (x: number, y: number) => number; // 上記の型エイリアスに適合する関数 const add: MathOperation = (a, b) => { return a + b; }; const subtract: MathOperation = (x, y) => x - y; // アロー関数の省略形 console.log(`add(5, 3) = ${add(5, 3)}`); console.log(`subtract(5, 3) = ${subtract(5, 3)}`); // --- 2. オプショナルパラメータ --- function greet(name: string, title?: string): string { if (title) { return `Hello, ${title} ${name}!`; } else { return `Hello, ${name}!`; } } console.log(greet("Hideki")); // title は省略 console.log(greet("Sato", "Mr.")); // --- 3. デフォルトパラメータ --- function power(base: number, exponent: number = 2): number { return Math.pow(base, exponent); // base の exponent 乗を計算 } console.log(`power(10) = ${power(10)}`); // exponent はデフォルト値の 2 を使用 console.log(`power(2, 8) = ${power(2, 8)}`); // exponent に 8 を指定 // --- 4. Restパラメータ --- function sumAll(...numbers: number[]): number { // numbers は number 型の配列になる let total = 0; for (const num of numbers) { total += num; } // または reduce を使う: return numbers.reduce((sum, current) => sum + current, 0); return total; } console.log(`sumAll(1, 2, 3) = ${sumAll(1, 2, 3)}`); console.log(`sumAll(10, 20, 30, 40, 50) = ${sumAll(10, 20, 30, 40, 50)}`); console.log(`sumAll() = ${sumAll()}`); // 引数なしでもOK (空の配列になる) // --- 5. this の型付け (おまけ) --- // 通常の関数とアロー関数での this の挙動の違いはJavaScriptの重要概念 // TypeScriptでは関数の第一引数に this を書くことで this の型を注釈できる (コンパイル時に消える) interface MyData { value: number; increment: () => void; } const myObj: MyData = { value: 10, increment: function(this: MyData) { // 通常関数では this の型を指定可能 console.log(`Incrementing value from ${this.value}`); this.value++; } }; // アロー関数は定義された場所の this を束縛する (ここではグローバル or undefined) // const myObjArrow: MyData = { // value: 20, // increment: () => { // // console.log(this.value); // strictモードやモジュール内では this が期待通りでない可能性 // } // }; myObj.increment(); console.log(`Value after increment: ${myObj.value}`);
-
コンパイルと実行:
npx tsc
でコンパイルし、node dist/functions.js
で実行して結果を確認してください。
-
コミットとPush:
src/functions.ts
の変更をコミットし (例:git commit -m "Add advanced function examples"
)、GitHubにPushしてください。- 新しいコミットへのリンクを教えてください。
関数の様々な記法や型付けを理解することは、TypeScriptを使いこなす上で非常に重要です。試してみてください!