TypeScript | 基礎文法:オブジェクト基礎 – プロパティに型を付ける

TypeScript
スポンサーリンク

「プロパティに型を付ける」とは何をしているのか

オブジェクトは「名前付きの値の集まり」です。
TypeScriptでは、その「名前付きの値」1つ1つに対して、「ここにはこういう型の値だけ入ってほしい」というルールを付けられます。
これが「プロパティに型を付ける」ということです。

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

この2行で、TypeScriptに対してこう宣言しています。

User という型のオブジェクトには、
name という string のプロパティと、
age という number のプロパティが必ずある」

ここから外れたオブジェクトを作ろうとすると、コンパイル時に止めてくれます。


基本構文:プロパティ名: 型

一番シンプルな形

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

name: string は「name プロパティには string を入れる」という意味です。
age: number は「age には number」、isAdmin: boolean は「isAdmin には true/false」というルールです。

この型を使ってオブジェクトを作るとき、TypeScriptはそのルールを厳しくチェックします。

const u1: User = {
  name: "Taro",
  age: 20,
  isAdmin: false,
}; // OK

const u2: User = {
  name: "Hanako",
  age: "20",
  isAdmin: false,
  // エラー: Type 'string' is not assignable to type 'number'.
};
TypeScript

「プロパティに型を付ける」とは、
「この名前の箱には、この種類の値だけ入れていい」と決めることだとイメージすると分かりやすいです。


プロパティの型に使えるもの

プリミティブ型(string, number, boolean など)

一番よく使うのは、基本の型です。

type Product = {
  id: number;
  name: string;
  price: number;
  inStock: boolean;
};
TypeScript

ここまでは直感通りだと思います。
「この項目は数字」「この項目は文字列」「この項目は真偽値」と、現実の意味とほぼ一致します。

オブジェクト型をプロパティに使う(入れ子構造)

プロパティの型として、別のオブジェクト型を使うこともできます。

type Address = {
  city: string;
  zip: string;
};

type User = {
  name: string;
  address: Address;
};
TypeScript

こうすると、

const u: User = {
  name: "Taro",
  address: {
    city: "Tokyo",
    zip: "100-0001",
  },
};
TypeScript

というように、「中にさらに構造を持ったオブジェクト」を入れられます。
プロパティに型を付ける、というのは「構造をどこまで細かく表現するか」を決める作業でもあります。

配列型をプロパティに使う

type User = {
  name: string;
  tags: string[];
};
TypeScript

tags: string[] は、「tags プロパティには string の配列が入る」という意味です。

const u: User = {
  name: "Taro",
  tags: ["admin", "paid"],
};
TypeScript

「ここはリスト」「ここは1つの値」という違いも、プロパティの型で表現できます。


オプションプロパティ(?)と型の関係

「あってもなくてもいい」プロパティ

すべてのプロパティが必須とは限りません。
「あるかもしれないし、ないかもしれない」項目には ? を付けます。

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

これは「age は number かもしれないし、そもそも存在しないかもしれない」という意味です。

const u1: User = { name: "Taro" };          // OK
const u2: User = { name: "Hanako", age: 18 }; // OK
TypeScript

使う側では、「ないかもしれない」ことを意識して書く必要があります。

function printUser(user: User) {
  console.log(user.name);
  if (user.age !== undefined) {
    console.log(user.age);
  }
}
TypeScript

? を付けるかどうかは、
「この項目は本当に必須か?」
という設計の話です。
「なんとなく全部オプション」にしてしまうと、逆に型の意味が弱くなります。


プロパティに型を付けることで防げるミス

1つの項目に違う型を入れてしまうミス

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

const u: User = {
  name: "Taro",
  age: "20", // 本当は number にしたかったのに…
};
TypeScript

JavaScriptならこのまま通ってしまいますが、TypeScriptはここで止めてくれます。
age は number だと約束したよね?」と。

プロパティ名の打ち間違い

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

const u: User = {
  name: "Taro",
  agge: 20,
  // Object literal may only specify known properties...
};
TypeScript

agge のようなタイプミスも、「そんなプロパティは User にない」と教えてくれます。
プロパティに型を付けることは、「名前のスペル」まで含めて仕様にしてしまう、ということでもあります。


初心者がまず掴んでおきたい「プロパティに型を付ける」感覚

プロパティに型を付ける、というのは単に「型注釈を書く作業」ではありません。
本質的には、こういうことをやっています。

「このオブジェクトは、こういう項目を持っているべきだ」
「この項目には、こういう種類の値だけ入っていてほしい」
「この項目は必須、この項目はあってもなくてもいい」

つまり、「データの形とルールを、自然言語ではなく型として書き下す」作業です。

ユーザー情報、商品情報、設定、レスポンスのJSON…
そういう「意味のあるまとまり」を見つけたら、
一度 { プロパティ名: 型 } の形で書き出してみる。

そこから、「型が設計を支えてくれる」感覚が、かなりはっきり見えてきます。

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