課題3: インターフェース (Interface) と 型エイリアス (Type Alias) (所要時間目安: 15‐25分) - hideki5123/myts GitHub Wiki
次は、オブジェクトの「形」を定義するための強力な方法である interface
と、型に別名を付ける type
エイリアスを学びましょう。
C#との比較:
-
interface
:- TypeScript: オブジェクトが持つべきプロパティやメソッドの型を定義します。構造的部分型(Structural Typing)の原則に基づき、オブジェクトが必要なプロパティ/メソッドを(正しい型で)持っていれば、明示的に
implements
しなくてもインターフェースを満たしているとみなされます。主にオブジェクトの形状定義に使われます。コンパイル時にのみ存在し、ランタイムのJavaScriptコードには残りません。 - C#: クラスが実装すべきメンバー(メソッド、プロパティ、イベントなど)のコントラクト(契約)を定義します。クラスはインターフェースを明示的に
implements
する必要があり、すべてのメンバーを実装しなければなりません。ランタイムにも型の情報として存在します。 - 類似点: 特定の構造や契約を定義する点。
- 相違点: TypeScriptは構造(アヒル)タイピング、C#は明示的な実装(ノミナルタイピング)。TypeScriptのInterfaceはコンパイル時のみ。
- TypeScript: オブジェクトが持つべきプロパティやメソッドの型を定義します。構造的部分型(Structural Typing)の原則に基づき、オブジェクトが必要なプロパティ/メソッドを(正しい型で)持っていれば、明示的に
-
type
エイリアス:- TypeScript: 既存の型(プリミティブ型、オブジェクト型、ユニオン型、タプル型など)に新しい名前(エイリアス)を付けます。複雑な型を再利用しやすくしたり、意図を明確にしたりするのに役立ちます。
- C#:
using
ディレクティブを使った型エイリアス (using UserId = System.Int32;
) に似ていますが、TypeScriptのtype
はより強力で、オブジェクトリテラル型、ユニオン型 (string | number
)、交差型 (A & B
) など、より複雑な型定義にも使えます。
課題内容:
-
新しいファイルの作成:
src
ディレクトリにinterfaces.ts
という新しいファイルを作成してください。 -
インターフェースの定義と使用:
interfaces.ts
に以下のようなコードを書いてみてください。// src/interfaces.ts // ユーザー情報を表すインターフェース interface User { id: number; name: string; email?: string; // ? を付けるとオプショナル(任意)なプロパティになる readonly isActive: boolean; // readonly を付けると再代入不可になる } // Userインターフェースを満たすオブジェクトを作成 const user1: User = { id: 1, name: "Hideki", // email: "[email protected]", // emailはオプショナルなので無くてもOK isActive: true, }; // 読み取り専用プロパティへの再代入はエラーになる // user1.isActive = false; // この行のコメントを外すとエラー // オプショナルプロパティを持つオブジェクト const user2: User = { id: 2, name: "Alice", email: "[email protected]", isActive: false, }; // インターフェースを型注釈として使う関数 function printUser(user: User): void { // void は関数が何も返さないことを示す型 (C#のvoidと同じ) console.log(`ID: ${user.id}, Name: ${user.name}, Active: ${user.isActive}`); if (user.email) { console.log(`Email: ${user.email}`); } } console.log("Printing users:"); printUser(user1); printUser(user2); // --- 型エイリアス --- // プリミティブ型のエイリアス type UserID = number; type UserName = string; // ユニオン型(複数の型のいずれかを表す)のエイリアス type StringOrNumber = string | number; let value1: StringOrNumber = "hello"; let value2: StringOrNumber = 123; // let value3: StringOrNumber = true; // boolean型は許可されていないのでエラー // オブジェクト形状のエイリアス (interface と似た使い方もできる) type Point = { x: number; y: number; }; const p1: Point = { x: 10, y: 20 }; console.log(`\nPoint: (${p1.x}, ${p1.y})`); // interface と type の主な違いの一つ: interfaceは同名で宣言するとマージされるが、typeはできない interface Box { height: number; width: number; } interface Box { scale: number; } const box: Box = { height: 5, width: 6, scale: 10 }; // OK、マージされる /* type Window { // 同じ名前で type は再宣言できない(エラーになる) title: string; } type Window { ts: any; } */
-
コンパイルと実行:
- ターミナルで
npx tsc
を実行してコンパイルします。 node dist/interfaces.js
を実行して結果を確認します。- エラーになる行のコメントを外して、コンパイル時に型エラーが検出されることを確認してください。
- ターミナルで
-
コミットとPush:
src/interfaces.ts
の変更をコミットし、GitHubにPushしてください (例:git commit -m "Add interfaces and type aliases examples"
)。- 新しいコミットへのリンクを教えてください。
インターフェースはTypeScriptで非常に頻繁に使われる重要な機能です。type
エイリアスもコードの可読性を高めるのに役立ちます。試してみてください!