はじめてのTypeScriptプログラミング入門 30日コース | ObjectとFunction - Day 8:Object

30日で身につけるTypeScript
スポンサーリンク
スポンサーリンク

Day 8:Objectで「ひとまとまりの情報」を表現する

Day 8では、配列に続いて「Object(オブジェクト)」を扱います。 オブジェクトは、ひとりのユーザー情報ひとつの商品情報のように、「いくつかの項目がセットになったデータ」を表現するのにぴったりな仕組みです。 今日は、ユーザー情報を題材にしながら、プロパティ・型・ネスト・Optional Property・readonly まで、ステップを追ってじっくり見ていきます。

Objectとは何かをイメージでつかむ

「名前付きの引き出し」が集まった箱

オブジェクトは、ざっくり言うと 「名前付きの引き出しが集まった箱」 のようなものです。

const user = {
  name: "Alice",
  age: 25,
  email: "alice@example.com",
};
TypeScript
  • name という引き出しに "Alice"
  • age という引き出しに 25
  • email という引き出しに "alice@example.com"

というように、「プロパティ名」と「値」がセットになっています。

プロパティと値:基本の書き方

プロパティ(property)

プロパティは、オブジェクトの「項目名」です。

const user = {
  name: "Alice", // プロパティ名: name
  age: 25,       // プロパティ名: age
};
TypeScript

値(value)

値は、そのプロパティに入っている実際のデータです。

  • name の値 → "Alice"(string)
  • age の値 → 25(number)
console.log(user.name); // "Alice"
console.log(user.age);  // 25
TypeScript

ポイント:

  • user.name のように、「オブジェクト名.プロパティ名」でアクセスします。
  • 配列が「番号」でアクセスするのに対して、オブジェクトは「名前」でアクセスするイメージです。

Objectの型を定義する:TypeScriptらしい書き方

TypeScriptでは、オブジェクトの「形」を型として定義できます。 これによって、「このオブジェクトは何の項目を持っていて、それぞれ何の型なのか」がはっきりします。

基本的なObjectの型

// ユーザー情報の型を定義
type User = {
  name: string; // 名前
  age: number;  // 年齢
  email: string; // メールアドレス
};

// 型を使ってオブジェクトを作成
const user: User = {
  name: "Alice",
  age: 25,
  email: "alice@example.com",
};

console.log(user.name);
console.log(user.age);
console.log(user.email);
TypeScript

重要ポイント:

  • type User = { ... } のようにして、「Userという型」を定義します。
  • その型を使って const user: User = { ... } と書くことで、「このオブジェクトはUser型ですよ」と宣言できます。
  • 型を定義しておくと、プロパティの書き忘れや、間違った型の代入をコンパイル時に教えてくれます。

ネスト(入れ子)されたObject:情報を階層的にまとめる

現実のデータは、もう少し複雑なことが多いです。 例えば、ユーザー情報の中に「住所情報」を含めたい場合、オブジェクトの中にオブジェクトを入れる「ネスト(入れ子)」が便利です。

ネストされたObjectの型

// 住所情報の型
type Address = {
  country: string; // 国
  city: string;    // 市区町村
  zipCode: string; // 郵便番号
};

// ユーザー情報の型(住所をネスト)
type User = {
  name: string;
  age: number;
  email: string;
  address: Address; // Address 型のプロパティ
};

const user: User = {
  name: "Alice",
  age: 25,
  email: "alice@example.com",
  address: {
    country: "Japan",
    city: "Tokyo",
    zipCode: "100-0001",
  },
};

console.log("名前:", user.name);
console.log("メール:", user.email);
console.log("住所(国):", user.address.country);
console.log("住所(市区町村):", user.address.city);
console.log("住所(郵便番号):", user.address.zipCode);
TypeScript

重要ポイント:

  • address プロパティの中に、さらに country, city, zipCode というプロパティを持つオブジェクトが入っています。
  • 「オブジェクトの中にオブジェクトが入っている」という構造は、現実世界の情報をそのままコードに持ち込むときにとても役立ちます。

Optional Property:あってもなくてもいい項目

ユーザー情報の中には、「必ずしも全員が持っているとは限らない項目」もあります。 例えば、「電話番号」や「ニックネーム」などです。 TypeScriptでは、そうした「任意の項目」を Optional Property として表現できます。

Optional Propertyの書き方

? を付けると、「あってもなくてもいいプロパティ」になります。

type User = {
  name: string;
  age: number;
  email: string;
  phone?: string; // Optional Property(あってもなくてもよい)
};

const user1: User = {
  name: "Alice",
  age: 25,
  email: "alice@example.com",
  phone: "090-1234-5678", // phone を持っているユーザー
};

const user2: User = {
  name: "Bob",
  age: 30,
  email: "bob@example.com",
  // phone は省略してもOK
};

console.log("Alice の電話番号:", user1.phone);
console.log("Bob の電話番号:", user2.phone); // undefined になる可能性がある
TypeScript

重要ポイント:

  • Optional Propertyは、「現実世界の“人によって違う”情報」を表現するのにぴったりです。
  • user2.phone は存在しないので、実行時には undefined になる可能性があります。
  • 実務では、Optional Propertyを扱うときに「存在チェック」をすることがよくあります。

readonly:変更できないプロパティを作る

セキュリティや安全性の観点から、「一度決めたら変えてはいけない情報」をコードで表現したくなることがあります。 例えば、「ユーザーID」や「登録日時」などです。 TypeScriptでは、readonly を使って「書き換え禁止のプロパティ」を定義できます。

readonlyの書き方

type User = {
  readonly id: number; // 一度決めたら変更できないID
  name: string;
  age: number;
  email: string;
};

const user: User = {
  id: 1,
  name: "Alice",
  age: 25,
  email: "alice@example.com",
};

console.log("ユーザーID:", user.id);

// user.id = 2; // コンパイルエラー:readonly プロパティは変更できない
user.name = "Alice Smith"; // name は変更可能

console.log("変更後の名前:", user.name);
TypeScript

重要ポイント:

  • readonly を付けることで、「このプロパティは後から書き換えてはいけない」というルールを型レベルで表現できます。
  • セキュリティやデータ整合性の観点から、「変わってはいけない値」を明示するのはとても大切です。
  • 実務でも、IDや作成日時などに readonly を使うことがよくあります。

実践:ユーザー情報オブジェクトを作成する

ここまでの内容をまとめて、ユーザー情報オブジェクトを作る実践コードを書いてみます。

ユーザー情報の型定義

// user.ts
// ユーザー情報の型とオブジェクトを定義する

// 住所情報の型
type Address = {
  country: string;
  city: string;
  zipCode: string;
};

// ユーザー情報の型
type User = {
  readonly id: number; // 変更できないユーザーID
  name: string;        // 名前
  age: number;         // 年齢
  email: string;       // メールアドレス
  address: Address;    // ネストされた住所情報
  phone?: string;      // Optional Property:電話番号(任意)
};

// ユーザー情報オブジェクトを作成
const user1: User = {
  id: 1,
  name: "Alice",
  age: 25,
  email: "alice@example.com",
  address: {
    country: "Japan",
    city: "Tokyo",
    zipCode: "100-0001",
  },
  phone: "090-1234-5678",
};

const user2: User = {
  id: 2,
  name: "Bob",
  age: 30,
  email: "bob@example.com",
  address: {
    country: "Japan",
    city: "Osaka",
    zipCode: "530-0001",
  },
  // phone は省略
};

// ユーザー情報を表示
console.log("=== ユーザー1 ===");
console.log("ID:", user1.id);
console.log("名前:", user1.name);
console.log("年齢:", user1.age);
console.log("メール:", user1.email);
console.log("住所:", user1.address.country, user1.address.city, user1.address.zipCode);
console.log("電話番号:", user1.phone);

console.log("\n=== ユーザー2 ===");
console.log("ID:", user2.id);
console.log("名前:", user2.name);
console.log("年齢:", user2.age);
console.log("メール:", user2.email);
console.log("住所:", user2.address.country, user2.address.city, user2.address.zipCode);
console.log("電話番号:", user2.phone); // undefined の可能性あり
TypeScript

ポイントのおさらい:

  • type User で「ユーザー情報の形」を定義
  • readonly id で「変更できないID」を表現
  • address: Address で「ネストされたオブジェクト」を使う
  • phone?: string で「任意の項目」を表現

もう一歩:ユーザー情報を配列で管理する

Day 6・Day 7で配列を扱ったので、オブジェクトと配列を組み合わせて「複数ユーザー」を管理する形も少しだけ見ておきます。

// users-list.ts
// 複数ユーザーを配列で管理する

type Address = {
  country: string;
  city: string;
  zipCode: string;
};

type User = {
  readonly id: number;
  name: string;
  age: number;
  email: string;
  address: Address;
  phone?: string;
};

// ユーザー一覧(配列)
const users: User[] = [
  {
    id: 1,
    name: "Alice",
    age: 25,
    email: "alice@example.com",
    address: {
      country: "Japan",
      city: "Tokyo",
      zipCode: "100-0001",
    },
    phone: "090-1234-5678",
  },
  {
    id: 2,
    name: "Bob",
    age: 30,
    email: "bob@example.com",
    address: {
      country: "Japan",
      city: "Osaka",
      zipCode: "530-0001",
    },
  },
];

console.log("=== ユーザー一覧 ===");

for (const user of users) {
  console.log("\nID:", user.id);
  console.log("名前:", user.name);
  console.log("年齢:", user.age);
  console.log("メール:", user.email);
  console.log("住所:", user.address.country, user.address.city, user.address.zipCode);

  if (user.phone) {
    console.log("電話番号:", user.phone);
  } else {
    console.log("電話番号: 未登録");
  }
}
TypeScript

ポイント:

  • User[] で「ユーザー情報の配列」を表現しています。
  • Optional Property phone を扱うときに、if (user.phone) のような存在チェックをしています。
  • ここまで来ると、「変数・条件分岐・ループ・配列・オブジェクト」が自然につながっているのが感じられるはずです。

Day 8のまとめ

Day 8では、

  • Objectの基本(プロパティと値)
  • Objectの型定義(type User = { ... }
  • ネストされたObjectで、住所などの階層的な情報を表現する方法
  • Optional Property(phone?: string)で「あってもなくてもいい項目」を表現する方法
  • readonly(readonly id)で「変更してはいけない値」を守る方法
  • 実践として、ユーザー情報オブジェクトを作成し、配列と組み合わせて複数ユーザーを管理する形

を一通り体験しました。

オブジェクトは、「現実世界のひとまとまりの情報」をそのままコードに持ち込める、とても頼りになる道具です。 今日のユーザー情報のコードは、ぜひ項目を増やしたり、Optional Propertyを追加したり、readonlyを付ける場所を変えたりしながら、自分なりの“情報モデル”に育ててみてください。

次のDayでは、Function(関数)に進みます。 オブジェクトと関数が使えるようになると、プログラムの表現力は一気に広がっていきます。


Day 8:Objectで「現実の情報」をそのままコードにしてみる

Day 8のテーマは Object(オブジェクト)です。 ここでは、商品・ユーザー・学生・会社・注文という、現実世界でよく登場する情報を、TypeScriptのオブジェクトとして表現していきます。 雑誌の記事を読むような感覚で、「こういう情報はこういう形で持てるんだ」とイメージしながら進めてみてください。

Objectの基本をもう一度整理する

Objectとは

Objectは、「名前付きの項目が集まったひとまとまりのデータ」です。

const user = {
  name: "Alice",
  age: 25,
  email: "alice@example.com",
};
TypeScript
  • name / age / emailプロパティ(項目名)
  • "Alice" / 25 / "alice@example.com"

user.name のように、「オブジェクト名.プロパティ名」でアクセスします。

Objectの型

TypeScriptでは、オブジェクトの「形」を型として定義できます。

type User = {
  name: string;
  age: number;
  email: string;
};
TypeScript

この型を使うことで、「このオブジェクトはUser型ですよ」と宣言でき、プロパティの抜けや型の間違いを防げます。

Step 1:商品Objectを作る

まずは、シンプルな「商品情報」から始めます。

商品情報に含めたい項目を考える

  • 商品ID(変更してはいけない)
  • 商品名
  • 価格
  • 在庫数
  • 説明文(Optionalでもよさそう)

商品Objectの型定義

// product.ts
// 商品情報の型とオブジェクト

type Product = {
  readonly id: number;   // 変更してはいけない商品ID
  name: string;          // 商品名
  price: number;         // 価格
  stock: number;         // 在庫数
  description?: string;  // Optional Property:説明文(任意)
};

const product1: Product = {
  id: 1001,
  name: "TypeScript入門本",
  price: 2800,
  stock: 50,
  description: "TypeScriptの基本構文をわかりやすく解説した入門書です。",
};

const product2: Product = {
  id: 1002,
  name: "ノートPCスタンド",
  price: 3500,
  stock: 20,
  // description は省略してもOK
};

console.log("=== 商品1 ===");
console.log("ID:", product1.id);
console.log("名前:", product1.name);
console.log("価格:", product1.price);
console.log("在庫数:", product1.stock);
console.log("説明:", product1.description);

console.log("\n=== 商品2 ===");
console.log("ID:", product2.id);
console.log("名前:", product2.name);
console.log("価格:", product2.price);
console.log("在庫数:", product2.stock);
console.log("説明:", product2.description); // undefined の可能性あり
TypeScript

深掘りポイント:

  • readonly id で「商品IDは後から変えてはいけない」というルールを型で表現しています。
  • description?: string は Optional Property で、「説明文がない商品もあり得る」という現実をそのままコードにしています。

Step 2:ユーザーObjectを作る

次は、「ユーザー情報」をオブジェクトで表現します。

ユーザー情報に含めたい項目

  • ユーザーID(readonly)
  • 名前
  • 年齢
  • メールアドレス
  • 住所(ネストされたObject)
  • 電話番号(Optional)

ユーザーObjectの型定義

// user.ts
// ユーザー情報の型とオブジェクト

type Address = {
  country: string; // 国
  city: string;    // 市区町村
  zipCode: string; // 郵便番号
};

type User = {
  readonly id: number; // 変更できないユーザーID
  name: string;        // 名前
  age: number;         // 年齢
  email: string;       // メールアドレス
  address: Address;    // ネストされた住所情報
  phone?: string;      // Optional Property:電話番号
};

const user1: User = {
  id: 1,
  name: "Alice",
  age: 25,
  email: "alice@example.com",
  address: {
    country: "Japan",
    city: "Tokyo",
    zipCode: "100-0001",
  },
  phone: "090-1234-5678",
};

const user2: User = {
  id: 2,
  name: "Bob",
  age: 30,
  email: "bob@example.com",
  address: {
    country: "Japan",
    city: "Osaka",
    zipCode: "530-0001",
  },
  // phone は省略
};

console.log("=== ユーザー1 ===");
console.log("ID:", user1.id);
console.log("名前:", user1.name);
console.log("年齢:", user1.age);
console.log("メール:", user1.email);
console.log("住所:", user1.address.country, user1.address.city, user1.address.zipCode);
console.log("電話番号:", user1.phone);

console.log("\n=== ユーザー2 ===");
console.log("ID:", user2.id);
console.log("名前:", user2.name);
console.log("年齢:", user2.age);
console.log("メール:", user2.email);
console.log("住所:", user2.address.country, user2.address.city, user2.address.zipCode);
console.log("電話番号:", user2.phone); // undefined の可能性あり
TypeScript

深掘りポイント:

  • ネストされた address オブジェクトが、「住所」というひとまとまりの情報をきれいに表現しています。
  • Optional Property phone は、「登録している人もいれば、していない人もいる」という現実をそのままコードにしています。

Step 3:学生Objectを作る

次は、「学生情報」をオブジェクトで表現します。

学生情報に含めたい項目

  • 学生ID(readonly)
  • 名前
  • 学年
  • クラス
  • 成績(ネストされたObject)
  • 部活動(Optional)

学生Objectの型定義

// student.ts
// 学生情報の型とオブジェクト

type GradeInfo = {
  japanese: number; // 国語
  math: number;     // 数学
  english: number;  // 英語
};

type Student = {
  readonly id: number; // 学生ID(変更不可)
  name: string;        // 名前
  grade: number;       // 学年
  className: string;   // クラス名
  scores: GradeInfo;   // ネストされた成績情報
  club?: string;       // Optional Property:部活動
};

const student1: Student = {
  id: 101,
  name: "Charlie",
  grade: 2,
  className: "2-A",
  scores: {
    japanese: 80,
    math: 90,
    english: 85,
  },
  club: "サッカー部",
};

const student2: Student = {
  id: 102,
  name: "Diana",
  grade: 3,
  className: "3-B",
  scores: {
    japanese: 70,
    math: 65,
    english: 75,
  },
  // club は未所属なので省略
};

console.log("=== 学生1 ===");
console.log("ID:", student1.id);
console.log("名前:", student1.name);
console.log("学年:", student1.grade);
console.log("クラス:", student1.className);
console.log("成績:", "国語", student1.scores.japanese, "数学", student1.scores.math, "英語", student1.scores.english);
console.log("部活動:", student1.club);

console.log("\n=== 学生2 ===");
console.log("ID:", student2.id);
console.log("名前:", student2.name);
console.log("学年:", student2.grade);
console.log("クラス:", student2.className);
console.log("成績:", "国語", student2.scores.japanese, "数学", student2.scores.math, "英語", student2.scores.english);
console.log("部活動:", student2.club); // undefined の可能性あり
TypeScript

深掘りポイント:

  • scores のようなネストされたオブジェクトは、「成績」というまとまりをきれいに表現しています。
  • Optional Property club は、「部活動に入っている学生もいれば、入っていない学生もいる」という状況を自然に表現できます。

Step 4:会社Objectを作る

次は、「会社情報」をオブジェクトで表現します。

会社情報に含めたい項目

  • 会社ID(readonly)
  • 会社名
  • 業種
  • 従業員数
  • 本社住所(ネスト)
  • WebサイトURL(Optional)

会社Objectの型定義

// company.ts
// 会社情報の型とオブジェクト

type CompanyAddress = {
  country: string;
  city: string;
  zipCode: string;
};

type Company = {
  readonly id: number;   // 会社ID(変更不可)
  name: string;          // 会社名
  industry: string;      // 業種
  employees: number;     // 従業員数
  headOffice: CompanyAddress; // 本社住所(ネスト)
  website?: string;      // Optional Property:WebサイトURL
};

const company1: Company = {
  id: 5001,
  name: "Tech Solutions Inc.",
  industry: "IT",
  employees: 120,
  headOffice: {
    country: "Japan",
    city: "Tokyo",
    zipCode: "101-0001",
  },
  website: "https://www.tech-solutions.example",
};

const company2: Company = {
  id: 5002,
  name: "Green Foods Co.",
  industry: "Food",
  employees: 80,
  headOffice: {
    country: "Japan",
    city: "Nagoya",
    zipCode: "460-0001",
  },
  // website は未登録
};

console.log("=== 会社1 ===");
console.log("ID:", company1.id);
console.log("会社名:", company1.name);
console.log("業種:", company1.industry);
console.log("従業員数:", company1.employees);
console.log("本社住所:", company1.headOffice.country, company1.headOffice.city, company1.headOffice.zipCode);
console.log("Webサイト:", company1.website);

console.log("\n=== 会社2 ===");
console.log("ID:", company2.id);
console.log("会社名:", company2.name);
console.log("業種:", company2.industry);
console.log("従業員数:", company2.employees);
console.log("本社住所:", company2.headOffice.country, company2.headOffice.city, company2.headOffice.zipCode);
console.log("Webサイト:", company2.website); // undefined の可能性あり
TypeScript

深掘りポイント:

  • headOffice のようなネストされたオブジェクトは、「本社住所」というまとまりを表現しています。
  • website?: string は、「Webサイトがある会社もあれば、ない会社もある」という現実をそのままコードにしています。

Step 5:注文Objectを作る

最後に、「注文情報」をオブジェクトで表現します。 ここでは、商品ObjectやユーザーObjectと組み合わせて、少しだけ“現実っぽい”形にしてみます。

注文情報に含めたい項目

  • 注文ID(readonly)
  • 注文者(User型)
  • 商品(Product型)
  • 注文数量
  • 合計金額(readonlyでもよい)
  • 備考(Optional)

注文Objectの型定義

// order.ts
// 注文情報の型とオブジェクト

// 先ほど定義した Product と User を再利用するとイメージしやすいです。
// ここでは簡略版を再定義します。

type Product = {
  readonly id: number;
  name: string;
  price: number;
};

type User = {
  readonly id: number;
  name: string;
  email: string;
};

type Order = {
  readonly id: number;   // 注文ID(変更不可)
  user: User;            // 注文者情報
  product: Product;      // 商品情報
  quantity: number;      // 注文数量
  readonly totalPrice: number; // 合計金額(変更不可)
  note?: string;         // Optional Property:備考
};

const user: User = {
  id: 1,
  name: "Alice",
  email: "alice@example.com",
};

const product: Product = {
  id: 1001,
  name: "TypeScript入門本",
  price: 2800,
};

const order1: Order = {
  id: 9001,
  user: user,
  product: product,
  quantity: 2,
  totalPrice: product.price * 2, // 合計金額を計算してセット
  note: "ギフト包装を希望",
};

console.log("=== 注文1 ===");
console.log("注文ID:", order1.id);
console.log("注文者:", order1.user.name, order1.user.email);
console.log("商品:", order1.product.name);
console.log("単価:", order1.product.price);
console.log("数量:", order1.quantity);
console.log("合計金額:", order1.totalPrice);
console.log("備考:", order1.note);
TypeScript

深掘りポイント:

  • Order 型の中で、user: Userproduct: Product として、他のオブジェクト型を再利用しています。
  • readonly totalPrice は、「注文時に決まった合計金額は後から勝手に変えてはいけない」というルールを表現しています。
  • Optional Property note は、「備考がある注文もあれば、ない注文もある」という状況を自然に表現できます。

Day 8 練習まとめテンプレート

最後に、今日の課題をひとつのファイルにざっくりまとめたテンプレートを載せておきます。 これをベースに、項目を増やしたり、値を変えたりしながら、自分なりのObject設計を試してみてください。

// day8-practice.ts
// Day 8:Object 総合練習

// 商品Object
type Product = {
  readonly id: number;
  name: string;
  price: number;
  stock: number;
  description?: string;
};

// ユーザーObject
type Address = {
  country: string;
  city: string;
  zipCode: string;
};

type User = {
  readonly id: number;
  name: string;
  age: number;
  email: string;
  address: Address;
  phone?: string;
};

// 学生Object
type GradeInfo = {
  japanese: number;
  math: number;
  english: number;
};

type Student = {
  readonly id: number;
  name: string;
  grade: number;
  className: string;
  scores: GradeInfo;
  club?: string;
};

// 会社Object
type CompanyAddress = {
  country: string;
  city: string;
  zipCode: string;
};

type Company = {
  readonly id: number;
  name: string;
  industry: string;
  employees: number;
  headOffice: CompanyAddress;
  website?: string;
};

// 注文Object
type SimpleProduct = {
  readonly id: number;
  name: string;
  price: number;
};

type SimpleUser = {
  readonly id: number;
  name: string;
  email: string;
};

type Order = {
  readonly id: number;
  user: SimpleUser;
  product: SimpleProduct;
  quantity: number;
  readonly totalPrice: number;
  note?: string;
};

// ここから先は、実際にオブジェクトを作って console.log で表示してみると理解が深まります。
TypeScript

Day 8のまとめ

Day 8では、

  • Objectの基本(プロパティと値)
  • Objectの型定義
  • ネストされたObjectで階層的な情報を表現する方法
  • Optional Propertyで「あってもなくてもいい項目」を表現する方法
  • readonlyで「変更してはいけない値」を守る方法
  • 商品・ユーザー・学生・会社・注文という、現実に近い情報をオブジェクトとして設計する練習

を一通り体験しました。

オブジェクトは、「現実世界のひとまとまりの情報」をそのままコードに持ち込める、とても強力な道具です。 今日のコードは、ぜひ項目を増やしたり、Optional Propertyを追加したり、readonlyを付ける場所を変えたりしながら、自分なりの“情報モデル”に育ててみてください。 次のステップで扱う Function(関数)と組み合わせると、いよいよ「動くアプリケーション」に近づいていきます。

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