Day 2・オブジェクト・配列・型に名前をつける
オプショナル(?)と読み取り専用(readonly)
あってもなくてもよいプロパティを ? で、書き換え禁止のプロパティを readonly で表す。
あるかもしれないし、ないかもしれないプロパティ
実際のデータでは「値があるとは限らない」プロパティがあります。たとえばユーザーの電話番号は、登録している人もいれば、していない人もいます。こういう「あってもなくてもよい」プロパティは、名前のうしろに ? をつけて表します。これを(オプショナル)と呼びます。
interface User {
name: string;
phone?: string; // ? があるので、あってもなくてもよい
}
const a: User = { name: "田中", phone: "090-0000-0000" }; // OK
const b: User = { name: "佐藤" }; // phone なしでもOKオプショナルは「undefinedかもしれない」
phone? があるプロパティは、値が入っていない場合 undefined(値なし)になります。そのため user.phone.length のようにいきなり中身を触ると、値がないときにエラーになります。使う前に「値があるか」を確認するのが基本です。次の例で確認します。
確認せずに使う
function show(u: User) {
return u.phone.length; // エラー: phone は undefined かもしれない
}あるか確認してから使う
function show(u: User) {
if (u.phone) {
return u.phone.length; // ここでは phone があると分かっている
}
return 0;
}なぜ ? が便利なのか
? を使うと「このプロパティは無いことがある」という現実をそのまま型に書けます。すると TypeScript が「無い場合の処理を書き忘れていないか」を見張ってくれます。値の有無を型で明示することが、実行時のエラーを未然に防ぎます。
書き換えてほしくないプロパティは readonly
逆に、一度決めたら変えてほしくないプロパティもあります。たとえばユーザーの id は途中で変わると困ります。プロパティの前に readonly をつけると、あとから書き換えられなくなります。
interface User {
readonly id: number;
name: string;
}
const user: User = { id: 1, name: "田中" };
user.name = "佐藤"; // OK(name は書き換え可能)
user.id = 2; // エラー: id は readonly なので書き換えられないAIにはこう使う
「id は変更されないはずだから readonly にして、phone は任意入力だから ? にして」とAIに伝えると、意図どおりの型を作ってくれます。? と readonly でデータのルール(任意なのか、固定なのか)を型に書いておけば、AIが書いた処理がそのルールを破ったときに自動で止められます。
- ? は「あってもなくてもよい」プロパティ(オプショナル)
- オプショナルは値がないと undefined になるので、使う前に有無を確認する
- readonly は「後から書き換えられない」プロパティ
- ? と readonly でデータのルールを型に書き込める
この2日間のまとめ
Day2 では、オブジェクトと配列に型をつけ、interface でデータの形に名前をつけ、APIのJSONを型で表す方法を学びました。? と readonly でプロパティのルールまで書けるようになりました。これで「実装はAIに任せ、型で守り、自分の言葉で説明する」土台ができています。
読んでも腑に落ちない所は、AIに噛み砕いてもらいましょう。
理解度チェック
答えられれば、面接で説明できる状態に一歩近づきます。
interface のプロパティに phone?: string と書いたとき、正しい説明はどれですか。
readonly id: number と定義したプロパティに対して起きることはどれですか。
オプショナル(?)なプロパティを扱うとき、なぜ「値があるか確認してから使う」必要があるのですか。
記述式です。まず自分の言葉で答えを考えてから、模範解答を開いて自己採点してください。