複雑なデータ構造をTypeScriptで記述するためには、インターフェース(interface)と型エイリアス(type)を使用します。これらをオブジェクト、配列、およびネストされた型と組み合わせて、複雑なコレクションを厳密に型付けできます。
ネストされたオブジェクトの場合:
interface Address { city: string; zip: number; } interface UserProfile { name: string; age: number; address: Address; }
異なる型の配列の場合:
// タプル let tuple: [string, number] = ['John', 30]; // ユニオン型を持つ配列 let arr: (string | number)[] = [1, 'a', 2, 'b']; // オブジェクトの配列 let users: UserProfile[] = [ {...}, {...} ];
構造が複雑でオプションフィールドがある場合は、?を使用し、Partial、Record、Mapped Types、または再帰的型を組み合わせてネストされたツリーの型を定義します。
質問: 異なる型の要素を持つ配列(例えば、[string, number, boolean])を記述するためにインターフェースを使用することはできますか?
回答: いいえ。そのような場合はタプルを使用する方が良いです — インターフェースは固定された位置と型には適していません。タプルは各位置での型を厳密に指定できます。
type MyTuple = [string, number, boolean]; let foo: MyTuple = ['ok', 12, false];
物語
プロジェクトで複雑な構造を誤って記述しました:混合型の配列に対してany[]を使用し、正しいタプルまたはユニオン型を使用しませんでした。その結果、要素の1つに誤った型の値が含まれ、ビジネスロジックでエラーが発生しました(文字列との算術演算)。
物語
データ構造内の深くネストされたオブジェクトが再帰型またはPartialを使用せずに宣言されていました。ツリーのノードに新しいサブツリーを追加しようとするとコンパイラエラーが発生し、開発者はanyへのダウンキャストでこれを回避していましたが、その後本番環境でランタイムバグが発生しました。
物語
ユーザープロファイルの説明を持つオブジェクトは部分的にオプションであるべきでしたが、開発者は?を使用しませんでした。サーバーからデータを取得した際にTypeScriptはエラーを報告せず、アプリケーションは存在しないフィールドにアクセスを試みてクラッシュしました。