文字列や数値だけでなく、オブジェクトの形にも型をつけられる。まずはユーザー情報の型を定義しよう。

type User = {
  name: string;
  level: number;
  isActive: boolean;
};

User は値ではなく、オブジェクトが持つプロパティの決まりなんですね。

そう。型名は大文字から始めるのが一般的だ。一度決めておけば、値にも関数の引数にも、同じ決まりを使える。

const user: User = {
  name: 'JavaScript',
  level: 1,
  isActive: true,
};

function showUserName(user: User) {
  console.log(user.name);
}

プロパティが足りなかったり、値の種類が違ったりすると教えてくれそうです。

その通り。なくてもよいプロパティは、名前の後ろに ? をつけて表せる。

type User = {
  name: string;
  level: number;
  nickname?: string;
};

これで nickname は省略できるんですね。

ただし、省略できるということは、値が undefined かもしれないということだ。使う側では、あるかどうかを確かめてから触ることになる。

if (user.nickname) {
  console.log(user.nickname.toUpperCase());
}

条件分岐が、ここで型の話とつながりました。

そこが面白いところだよ。if を通り抜けた中では、nicknamestring だとTypeScriptも分かっている。

取りうる値を限定したいときは、ユニオン型が便利だ。

type Status = 'draft' | 'published';

const articleStatus: Status = 'draft';

Status には、この2つの文字列以外を入れられないんですね。

打ち間違いもその場で分かるし、読む人には「状態はこの2つだけ」という設計の意図が伝わる。

データの形や取りうる状態を型で表しておくと、あとから読む人が助かる。型エラーは邪魔者ではなく、自分で決めたルールとの食い違いを知らせてくれる案内役だと考えよう。

最後は、まとめた値をどう処理するかだ。