はじめてのTypeScriptプログラミング入門 30日コース | TypeScriptの核心「型」 - Day 16:Interface

30日で身につけるTypeScript
スポンサーリンク
スポンサーリンク
  1. Day 16:Interfaceで「商品管理の型設計」をしてみる
  2. interfaceとは:Objectの「設計図」を表すもの
    1. interfaceの基本イメージ
  3. interfaceとtypeの違いをざっくり知っておく
  4. 商品管理の世界をイメージする
  5. Step 1:Productインターフェースを作る
    1. 商品の基本情報を設計する
  6. Step 2:Optionalプロパティを使う(任意項目)
    1. 「あってもなくてもいい」プロパティを表現する
  7. Step 3:readonlyで「書き換え禁止」を表現する
    1. IDなど「変わってはいけない値」を守る
  8. Step 4:Categoryインターフェースを作る(再利用の準備)
    1. 商品カテゴリを表現する
  9. Step 5:ProductとCategoryを組み合わせる
    1. カテゴリ付き商品インターフェース
  10. Step 6:在庫管理インターフェースを作る
    1. Inventoryインターフェース
  11. Step 7:商品管理全体をまとめるインターフェース
    1. ProductManagerインターフェース(設計図としての再利用)
  12. Day 16 練習テンプレート:商品管理の型をInterfaceで設計
  13. Day 16のまとめ
  14. Day 16:Interfaceで「User / Product / Order / Employee」を設計する
  15. interfaceの基本:オブジェクトの「設計図」を作る
    1. interfaceのイメージ
  16. Step 1:Userインターフェースを作る
    1. Userの基本設計
  17. Step 2:Productインターフェースを作る
    1. Productの基本設計
  18. Step 3:Orderインターフェースを作る(Interfaceの再利用)
    1. Orderの基本設計
  19. Step 4:Employeeインターフェースを作る
    1. Employeeの基本設計
  20. Day 16 演習テンプレート:4つのInterfaceをまとめる
  21. Day 16のまとめ

Day 16:Interfaceで「商品管理の型設計」をしてみる

第3週はTypeScriptの核心である「型」をじっくり育てていく週です。 Day 16のテーマは Interface。 昨日の type によるType Aliasに続いて、今日は interfaceでObjectの型を設計する感覚を身につけていきます。

学習内容は次のとおりです。

  • interface
  • プロパティ
  • Optional(任意プロパティ)
  • readonly(読み取り専用)
  • Interfaceの再利用

実践として、商品管理の型をInterfaceで設計していきます。

interfaceとは:Objectの「設計図」を表すもの

interfaceの基本イメージ

interface は、Objectの形(プロパティとその型)を表す「設計図」だと思ってください。

// ユーザーの設計図
interface User {
  id: number;
  name: string;
  email: string;
}
TypeScript

この User interfaceは、

  • id は number
  • name は string
  • email は string

という「ルール」を表しています。

const user: User = {
  id: 1,
  name: "Taro",
  email: "[email protected]",
};
TypeScript

のように使うことで、「このオブジェクトはUserの設計図どおりに作られている」とTypeScriptに伝えることができます。

interfaceとtypeの違いをざっくり知っておく

細かい違いは後で少しずつ覚えていけば大丈夫ですが、今の段階では次くらいのイメージで十分です。

  • type:型に名前をつけるための「汎用的なラベル」
  • interface:主に「Objectの形」を表すための「設計図」

どちらもObject Typeを表現できますが、interfaceは「オブジェクトの設計図」というニュアンスが強いので、 「データ構造」や「APIのレスポンス」などを表すときに好んで使われることが多いです。

商品管理の世界をイメージする

今日の実践テーマは 商品管理の型をInterfaceで設計することです。 ざっくり、次のような登場人物を考えてみます。

  • 商品(Product)
  • カテゴリ(Category)
  • 在庫情報(Inventory)
  • 注文(Order)
  • 顧客(Customer)

このうち、今日は特に「商品管理」に関係する型を中心に設計していきます。

Step 1:Productインターフェースを作る

商品の基本情報を設計する

まずは、商品そのものを表す Product interface を作ります。

// 商品を表すインターフェース
interface Product {
  id: number;       // 商品ID
  name: string;     // 商品名
  price: number;    // 価格
  stock: number;    // 在庫数
}
TypeScript

これで、「商品は必ず id, name, price, stock を持つ」というルールができました。

// Productインターフェースを使った変数
const product1: Product = {
  id: 100,
  name: "ノートPC",
  price: 120000,
  stock: 5,
};
TypeScript

重要ポイント:

  • interfaceは「このオブジェクトはこういう形をしているべき」という約束を表します。
  • Product を使うことで、商品管理プログラムの中で「商品オブジェクトの形」が統一されます。

Step 2:Optionalプロパティを使う(任意項目)

「あってもなくてもいい」プロパティを表現する

商品によっては、「説明文」があったりなかったりします。 こうした「任意の項目」は、? を使ってOptionalプロパティとして表現できます。

// 商品説明をOptionalにしたProductインターフェース
interface ProductWithDescription {
  id: number;
  name: string;
  price: number;
  stock: number;
  description?: string; // 任意プロパティ(あってもなくてもよい)
}

// 説明ありの商品
const product2: ProductWithDescription = {
  id: 101,
  name: "マウス",
  price: 2000,
  stock: 50,
  description: "ワイヤレスマウス",
};

// 説明なしの商品
const product3: ProductWithDescription = {
  id: 102,
  name: "キーボード",
  price: 5000,
  stock: 20,
  // description は省略可能
};
TypeScript

深掘りポイント:

  • description?: string; のように ? を付けると、「このプロパティは存在しない場合もある」という意味になります。
  • Optionalプロパティを使うことで、「必須項目」と「任意項目」を型レベルで区別できます。
  • 実際のアプリでは、「必須入力項目」と「任意入力項目」をこうした型で表現しておくと、バリデーションやフォーム設計がしやすくなります。

Step 3:readonlyで「書き換え禁止」を表現する

IDなど「変わってはいけない値」を守る

商品IDのように、「一度決まったら変わってはいけない値」は、readonly を使って「書き換え禁止」にできます。

// IDを読み取り専用にしたProductインターフェース
interface ProductReadonlyId {
  readonly id: number; // 読み取り専用
  name: string;
  price: number;
  stock: number;
}

const product4: ProductReadonlyId = {
  id: 200,
  name: "ディスプレイ",
  price: 30000,
  stock: 10,
};

// 読み取り専用プロパティは再代入できない
// product4.id = 300; // エラー:readonlyなので書き換え不可
TypeScript

重要ポイント:

  • readonly を付けると、「このプロパティは一度設定したら変更できない」というルールになります。
  • IDや作成日時など、「変わると困る値」に readonly を付けておくと、うっかり書き換えを防げます。
  • セキュリティや整合性の観点からも、「変わってはいけない値」を型で守るのはとても大事な考え方です。

Step 4:Categoryインターフェースを作る(再利用の準備)

商品カテゴリを表現する

商品管理では、「カテゴリ」を持つことがよくあります。 例えば、「PC」「周辺機器」「アクセサリ」などです。

// 商品カテゴリを表すインターフェース
interface Category {
  id: number;      // カテゴリID
  name: string;    // カテゴリ名
  description?: string; // 任意の説明
}

const categoryPc: Category = {
  id: 1,
  name: "PC",
  description: "パソコン本体",
};

const categoryPeripheral: Category = {
  id: 2,
  name: "周辺機器",
};
TypeScript

ポイント:

  • Categoryもinterfaceで「設計図」として表現しておくことで、商品との関連付けがしやすくなります。
  • Optionalプロパティを使って、「説明があるカテゴリ」と「説明がないカテゴリ」を自然に扱えます。

Step 5:ProductとCategoryを組み合わせる

カテゴリ付き商品インターフェース

Product と Category を組み合わせて、「カテゴリ付き商品」を表現してみます。

// カテゴリ付き商品を表すインターフェース
interface ProductWithCategory {
  readonly id: number; // IDは読み取り専用
  name: string;
  price: number;
  stock: number;
  category: Category;  // Categoryインターフェースを再利用
}

const product5: ProductWithCategory = {
  id: 300,
  name: "ゲーミングノートPC",
  price: 200000,
  stock: 3,
  category: categoryPc,
};
TypeScript

深掘りポイント:

  • category: Category; のように書くことで、「商品はCategory型のカテゴリを持つ」と宣言できます。
  • interface同士を組み合わせることで、現実世界の構造をそのままコードに落とし込めます。
  • readonly id と category: Category のように、「変わらないもの」と「関連するもの」を型で表現しておくと、コードの意図がとても伝わりやすくなります。

Step 6:在庫管理インターフェースを作る

Inventoryインターフェース

商品管理では、「在庫情報」を別の構造で持つこともあります。 例えば、倉庫ごとの在庫数などです。

// 在庫情報を表すインターフェース
interface Inventory {
  productId: number; // 商品ID
  location: string;  // 保管場所(倉庫名など)
  quantity: number;  // 在庫数
}

const inventory1: Inventory = {
  productId: 300,
  location: "東京倉庫",
  quantity: 2,
};
TypeScript

ポイント:

  • Inventoryは、「商品そのもの」ではなく「商品に紐づく在庫情報」を表します。
  • こうした「関連情報」を別インターフェースとして切り出しておくと、データ構造が整理されます。

Step 7:商品管理全体をまとめるインターフェース

ProductManagerインターフェース(設計図としての再利用)

最後に、「商品管理システムのインターフェース」をざっくり設計してみます。 ここでは、商品一覧とカテゴリ一覧を持つだけのシンプルな例にします。

// 商品管理システム全体を表すインターフェース
interface ProductManager {
  products: ProductWithCategory[]; // カテゴリ付き商品の一覧
  categories: Category[];          // カテゴリ一覧
}

// ProductManagerを使った例
const manager: ProductManager = {
  products: [product5],
  categories: [categoryPc, categoryPeripheral],
};

console.log("商品管理システム:", manager);
TypeScript

重要ポイント:

  • ProductManager は、「商品管理システムがどんなデータを持っているか」の設計図です。
  • interfaceを重ねていくことで、「システム全体の構造」を型として表現できるようになります。
  • ここまでで、Product / ProductWithDescription / ProductReadonlyId / Category / ProductWithCategory / Inventory / ProductManager と、複数のインターフェースを設計しました。

Day 16 練習テンプレート:商品管理の型をInterfaceで設計

最後に、今日の内容をひとつのファイルにまとめた練習テンプレートを載せます。 このままコピーして、プロパティを増やしたり、関数型を追加したりしながら、自分なりの「商品管理の型設計」を試してみてください。

// day16-interface-product.ts
// Day 16:Interfaceで商品管理の型を設計する

// 商品の基本インターフェース
interface Product {
  id: number;
  name: string;
  price: number;
  stock: number;
}

// Optionalプロパティ付き商品
interface ProductWithDescription {
  id: number;
  name: string;
  price: number;
  stock: number;
  description?: string; // 任意の説明
}

// readonly付き商品
interface ProductReadonlyId {
  readonly id: number; // 読み取り専用ID
  name: string;
  price: number;
  stock: number;
}

// カテゴリ
interface Category {
  id: number;
  name: string;
  description?: string;
}

// カテゴリ付き商品
interface ProductWithCategory {
  readonly id: number;
  name: string;
  price: number;
  stock: number;
  category: Category;
}

// 在庫情報
interface Inventory {
  productId: number;
  location: string;
  quantity: number;
}

// 商品管理システム全体
interface ProductManager {
  products: ProductWithCategory[];
  categories: Category[];
}

// テストデータ
const categoryPc: Category = {
  id: 1,
  name: "PC",
  description: "パソコン本体",
};

const categoryPeripheral: Category = {
  id: 2,
  name: "周辺機器",
};

const product5: ProductWithCategory = {
  id: 300,
  name: "ゲーミングノートPC",
  price: 200000,
  stock: 3,
  category: categoryPc,
};

const manager: ProductManager = {
  products: [product5],
  categories: [categoryPc, categoryPeripheral],
};

console.log("商品管理システム:", manager);
TypeScript

Day 16のまとめ

Day 16では、

  • interface を使ってObjectの「設計図」を表現する基本
  • プロパティに ? を付けてOptional(任意項目)を表現する方法
  • readonly で「変わってはいけない値」を守る考え方
  • Category や Inventory などのインターフェースを組み合わせて、「商品管理システム全体の構造」を型として表現する流れ

を、具体的なコードとともに体験しました。

interfaceは、TypeScriptで現実世界のデータ構造を表現するときの主役のひとつです。 ぜひ、プロパティを増やしたり、Optionalやreadonlyを使い分けたりしながら、自分なりの「商品管理の設計図」を描いてみてください。型で構造を描けるようになると、コードの意図がぐっとクリアに見えてきます。


Day 16:Interfaceで「User / Product / Order / Employee」を設計する

第3週は、TypeScriptの核心である「型」をじっくり育てていく週です。 Day 16の演習テーマは、interfaceを使って4つの型を設計することです。

  • User
  • Product
  • Order
  • Employee

学習内容は次のとおりです。

  • interface
  • プロパティ
  • Optional(任意プロパティ)
  • readonly(読み取り専用)
  • Interfaceの再利用

ここでは、現実の業務システムをイメージしながら、初心者の方にもわかりやすい形で、ステップバイステップで設計していきます。

interfaceの基本:オブジェクトの「設計図」を作る

interfaceのイメージ

interface は、オブジェクトの形(プロパティとその型)を表す設計図です。

interface User {
  id: number;
  name: string;
  email: string;
}
TypeScript

この User は、

  • id は number
  • name は string
  • email は string

というルールを表しています。

const user: User = {
  id: 1,
  name: "Taro",
  email: "[email protected]",
};
TypeScript

のように使うことで、「このオブジェクトはUserの設計図どおりに作られている」とTypeScriptに伝えることができます。

Step 1:Userインターフェースを作る

Userの基本設計

まずは、アプリでよく登場する「ユーザー」を表す User interface を作ります。 ここでは、次のような情報を持つユーザーを想定します。

  • id: ユーザーID(数値)
  • name: 名前(文字列)
  • email: メールアドレス(文字列)
  • isActive: 有効ユーザーかどうか(真偽値)
  • phone: 電話番号(任意)
// ユーザーを表すインターフェース
interface User {
  readonly id: number; // 読み取り専用ID(後から変えない前提)
  name: string;        // 名前
  email: string;       // メールアドレス
  isActive: boolean;   // 有効ユーザーかどうか
  phone?: string;      // 任意の電話番号(Optional)
}

// Userインターフェースを使った例
const user1: User = {
  id: 1,
  name: "Taro",
  email: "[email protected]",
  isActive: true,
  phone: "090-1234-5678",
};

const user2: User = {
  id: 2,
  name: "Hanako",
  email: "[email protected]",
  isActive: false,
  // phone は省略可能
};

// readonlyの確認
// user1.id = 10; // エラー:readonlyなので書き換え不可
TypeScript

重要ポイント:

  • readonly id にすることで、「ユーザーIDは一度決まったら変えない」という意図を型で表現できます。
  • phone?: string のように ? を付けると、「あってもなくてもよい」任意プロパティになります。
  • 必須項目と任意項目を型で区別しておくと、フォーム設計やバリデーションがとてもやりやすくなります。

Step 2:Productインターフェースを作る

Productの基本設計

次に、「商品」を表す Product interface を作ります。 ここでは、次のような情報を持つ商品を想定します。

  • id: 商品ID(数値)
  • name: 商品名(文字列)
  • price: 価格(数値)
  • stock: 在庫数(数値)
  • description: 商品説明(任意)
// 商品を表すインターフェース
interface Product {
  readonly id: number; // 読み取り専用ID
  name: string;        // 商品名
  price: number;       // 価格
  stock: number;       // 在庫数
  description?: string; // 任意の説明
}

// Productインターフェースを使った例
const product1: Product = {
  id: 100,
  name: "ノートPC",
  price: 120000,
  stock: 5,
  description: "開発者向けハイスペックノートPC",
};

const product2: Product = {
  id: 101,
  name: "マウス",
  price: 2000,
  stock: 50,
  // description は省略可能
};
TypeScript

ポイント:

  • 商品IDも readonly にしておくことで、「商品を識別するキー」が勝手に書き換えられるのを防げます。
  • description をOptionalにすることで、「説明がある商品」と「説明がない商品」を自然に扱えます。

Step 3:Orderインターフェースを作る(Interfaceの再利用)

Orderの基本設計

Order は「注文」を表すインターフェースです。 ここでは、次のような情報を持つ注文を想定します。

  • id: 注文ID(数値)
  • user: 注文者(User)
  • products: 注文された商品一覧(Product の配列)
  • totalPrice: 合計金額(数値)
  • note: 備考(任意)
// 注文を表すインターフェース
interface Order {
  readonly id: number;   // 注文ID
  user: User;            // 注文者(Userインターフェースを再利用)
  products: Product[];   // 注文された商品一覧(Productの配列)
  totalPrice: number;    // 合計金額
  note?: string;         // 任意の備考
}

// Orderインターフェースを使った例
const order1: Order = {
  id: 1000,
  user: user1, // 先ほど定義した user1 を再利用
  products: [product1, product2],
  totalPrice: 122000,
  note: "翌日配送希望",
};

const order2: Order = {
  id: 1001,
  user: user2,
  products: [product2],
  totalPrice: 2000,
  // note は省略可能
};
TypeScript

深掘りポイント:

  • user: User; と products: Product[]; のように、他のインターフェースを再利用しているのがポイントです。
  • interface同士を組み合わせることで、「現実世界の関係(ユーザーが商品を注文する)」をそのまま型として表現できます。
  • readonly id によって、「注文IDも変わらない識別子」であることを保証できます。

Step 4:Employeeインターフェースを作る

Employeeの基本設計

最後に、「従業員」を表す Employee interface を作ります。 ここでは、次のような情報を持つ従業員を想定します。

  • id: 従業員ID(数値)
  • name: 名前(文字列)
  • email: メールアドレス(文字列)
  • role: 役割(文字列)
  • manager: 上長(Employee、任意)
// 従業員を表すインターフェース
interface Employee {
  readonly id: number; // 従業員ID
  name: string;        // 名前
  email: string;       // メールアドレス
  role: string;        // 役割(例: "manager", "staff" など)
  manager?: Employee;  // 上長(任意・Employeeを再利用)
}

// Employeeインターフェースを使った例
const managerEmployee: Employee = {
  id: 500,
  name: "Manager A",
  email: "[email protected]",
  role: "manager",
};

const staffEmployee: Employee = {
  id: 501,
  name: "Staff B",
  email: "[email protected]",
  role: "staff",
  manager: managerEmployee, // 上長を紐づけ
};
TypeScript

重要ポイント:

  • manager?: Employee; のように、自分自身のインターフェースを再利用することで、「階層構造」を表現できます。
  • Optionalにしているので、「上長がいないトップの人」と「上長がいるスタッフ」の両方を自然に扱えます。
  • こうした自己参照的な構造は、組織図やツリー構造を表現するときに役立ちます。

Day 16 演習テンプレート:4つのInterfaceをまとめる

最後に、今日作った4つのインターフェースをひとつのファイルにまとめた練習テンプレートを載せます。 このままコピーして、プロパティを増やしたり、Optionalやreadonlyを使い分けたりしながら、自分なりの「型設計」を試してみてください。

// day16-interface-practice.ts
// Day 16:Interface 演習テンプレート

// Userインターフェース
interface User {
  readonly id: number;
  name: string;
  email: string;
  isActive: boolean;
  phone?: string;
}

// Productインターフェース
interface Product {
  readonly id: number;
  name: string;
  price: number;
  stock: number;
  description?: string;
}

// Orderインターフェース
interface Order {
  readonly id: number;
  user: User;
  products: Product[];
  totalPrice: number;
  note?: string;
}

// Employeeインターフェース
interface Employee {
  readonly id: number;
  name: string;
  email: string;
  role: string;
  manager?: Employee;
}

// テストデータ
const user1: User = {
  id: 1,
  name: "Taro",
  email: "[email protected]",
  isActive: true,
  phone: "090-1234-5678",
};

const user2: User = {
  id: 2,
  name: "Hanako",
  email: "[email protected]",
  isActive: false,
};

const product1: Product = {
  id: 100,
  name: "ノートPC",
  price: 120000,
  stock: 5,
  description: "開発者向けハイスペックノートPC",
};

const product2: Product = {
  id: 101,
  name: "マウス",
  price: 2000,
  stock: 50,
};

const order1: Order = {
  id: 1000,
  user: user1,
  products: [product1, product2],
  totalPrice: 122000,
  note: "翌日配送希望",
};

const managerEmployee: Employee = {
  id: 500,
  name: "Manager A",
  email: "[email protected]",
  role: "manager",
};

const staffEmployee: Employee = {
  id: 501,
  name: "Staff B",
  email: "[email protected]",
  role: "staff",
  manager: managerEmployee,
};

console.log("User1:", user1);
console.log("Product1:", product1);
console.log("Order1:", order1);
console.log("Manager:", managerEmployee);
console.log("Staff:", staffEmployee);
TypeScript

Day 16のまとめ

Day 16では、

  • interface を使ってObjectの「設計図」を表現する基本
  • readonly で「変わってはいけない値」を守る考え方
  • ? を使ってOptionalプロパティ(任意項目)を表現する方法
  • User / Product / Order / Employee の4つのインターフェースを設計し、互いに再利用しながら現実世界の関係を型として表現する流れ

を、具体的なコードとともに体験しました。

interfaceは、TypeScriptで現実世界のデータ構造やシステムの設計図を描くときの主役のひとつです。 ぜひ、プロパティを増やしたり、Optionalやreadonlyを使い分けたりしながら、自分なりの「User / Product / Order / Employee」の世界を設計してみてください。型で構造を描けるようになると、コードの意図がぐっとクリアに見えてきます。

タイトルとURLをコピーしました