- Day 16:Interfaceで「商品管理の型設計」をしてみる
- interfaceとは:Objectの「設計図」を表すもの
- interfaceとtypeの違いをざっくり知っておく
- 商品管理の世界をイメージする
- Step 1:Productインターフェースを作る
- Step 2:Optionalプロパティを使う(任意項目)
- Step 3:readonlyで「書き換え禁止」を表現する
- Step 4:Categoryインターフェースを作る(再利用の準備)
- Step 5:ProductとCategoryを組み合わせる
- Step 6:在庫管理インターフェースを作る
- Step 7:商品管理全体をまとめるインターフェース
- Day 16 練習テンプレート:商品管理の型をInterfaceで設計
- Day 16のまとめ
- Day 16:Interfaceで「User / Product / Order / Employee」を設計する
- interfaceの基本:オブジェクトの「設計図」を作る
- Step 1:Userインターフェースを作る
- Step 2:Productインターフェースを作る
- Step 3:Orderインターフェースを作る(Interfaceの再利用)
- Step 4:Employeeインターフェースを作る
- Day 16 演習テンプレート:4つのInterfaceをまとめる
- 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はnumbernameはstringemailは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);
TypeScriptDay 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はnumbernameはstringemailは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);
TypeScriptDay 16のまとめ
Day 16では、
interfaceを使ってObjectの「設計図」を表現する基本readonlyで「変わってはいけない値」を守る考え方?を使ってOptionalプロパティ(任意項目)を表現する方法User/Product/Order/Employeeの4つのインターフェースを設計し、互いに再利用しながら現実世界の関係を型として表現する流れ
を、具体的なコードとともに体験しました。
interfaceは、TypeScriptで現実世界のデータ構造やシステムの設計図を描くときの主役のひとつです。 ぜひ、プロパティを増やしたり、Optionalやreadonlyを使い分けたりしながら、自分なりの「User / Product / Order / Employee」の世界を設計してみてください。型で構造を描けるようになると、コードの意図がぐっとクリアに見えてきます。
