optionalプロパティとは何か(「あってもなくてもいい」項目)
オブジェクトのプロパティには、「必ず必要なもの」と「なくてもよいもの」があります。
TypeScriptでは、「なくてもよいプロパティ」を ? を使って表現します。これが optional(オプショナル)プロパティです。
type User = {
name: string;
age?: number;
};
TypeScriptこの age?: number は、「age プロパティはあってもいいし、なくてもいい。あるなら number」という意味になります。
フォームの「任意項目」と同じイメージで、「この情報はあるかもしれないし、ないかもしれない」を型として表現しているわけです。
基本構文:プロパティ名のあとに ? を付ける
type でのoptionalプロパティ
type User = {
name: string;
age?: number;
};
TypeScriptここで決まるルールはこうです。
nameは必須(string が必ず必要)ageは任意(あってもなくてもよい。あるなら number)
実際のオブジェクトは、どちらもOKです。
const u1: User = { name: "Taro" };
const u2: User = { name: "Hanako", age: 18 };
TypeScriptage を完全に省略してもエラーになりません。
「プロパティ自体が存在しないことを許可する」のが optional プロパティです。
interface でも同じ書き方
interface User {
name: string;
age?: number;
}
TypeScripttype と interface のどちらでも、optional の書き方は同じです。? が付いているかどうかだけで、「必須か任意か」が一目で分かります。
optionalプロパティの実際の型イメージ
「あるかもしれないし、ないかもしれない」
age?: number と書いたとき、TypeScript的には「age プロパティは存在しないか、存在するなら number」という意味になります。
つまり、User 型の値はざっくりこういうイメージです。
// OKな例
{ name: "Taro" }
{ name: "Taro", age: 20 }
TypeScriptage が「必ず number」ではなく、「number か undefined か、そもそもプロパティがないかもしれない」という前提で扱われます。
この「不確実さ」を型で表現しているのが optional プロパティです。
optionalプロパティを使うときに大事なポイント
使う側では「ないかもしれない」をちゃんと意識する
type User = {
name: string;
age?: number;
};
function printUser(user: User) {
console.log(user.name);
console.log(user.age.toFixed(1)); // エラー
}
TypeScriptここで user.age は「number かもしれないし、ないかもしれない」ので、
そのまま toFixed を呼ぼうとすると「undefined の可能性がある」と怒られます。
正しくは、存在チェックを挟みます。
function printUser(user: User) {
console.log(user.name);
if (user.age !== undefined) {
console.log(user.age.toFixed(1));
}
}
TypeScriptoptional にするということは、「このプロパティがないケースもちゃんと扱う」責任を呼び出し側が負うということです。
optionalプロパティと「undefinedを入れる」の違い
age?: number と age: number | undefined は微妙に違う
type A = {
age?: number;
};
type B = {
age: number | undefined;
};
TypeScriptA は「age プロパティ自体がないこともある」型です。B は「age プロパティは必ず存在するが、その値が undefined のこともある」型です。
const a1: A = {}; // OK(age 自体がない)
const a2: A = { age: 20 }; // OK
const b1: B = {}; // エラー(age が必須)
const b2: B = { age: undefined }; // OK
const b3: B = { age: 20 }; // OK
TypeScriptoptional プロパティは「プロパティの有無」ごと不確実にするのに対して、number | undefined は「プロパティはあるが中身が不確実」という違いがあります。
設計としてどちらが正しいかを意識して選ぶのが大事です。
optionalプロパティが活きる典型的な場面
フォームや設定の「任意項目」
type ProfileForm = {
name: string;
nickname?: string;
bio?: string;
};
TypeScriptnickname や bio のような「書いてもいいし、書かなくてもいい」項目は、optional プロパティで表現すると自然です。
「この情報は必須ではない」という仕様が、そのまま型に刻まれます。
APIレスポンスで「返ってくるかもしれないフィールド」
type UserResponse = {
id: number;
name: string;
email?: string;
};
TypeScript「古いユーザーには email がない」「権限によって email が省略される」といったケースでは、email を optional にしておくことで、「ないケースもある」ことを型で強制できます。
初心者がまず掴んでおきたい optionalプロパティの感覚
optional プロパティの本質は、たったひとつです。
「このプロパティは、常にあるとは限らない」ことを、型としてはっきり宣言する。
その結果として、
- オブジェクトを作るときに、そのプロパティを省略できる
- 使うときには「ないかもしれない」ことを必ず意識させられる
- 「任意項目」「条件付きで存在する項目」を安全に扱える
という状態になります。
「この情報、本当に必須?」
「このフィールド、APIから常に返ってくる?」
そう自分に問いかけて、「必須じゃない」と思ったら ? を付ける。
そして、使うときには「ないときの振る舞い」をちゃんと書く。
この往復ができるようになると、optional プロパティはただの記号ではなく、
「不確実さをコントロールするための設計ツール」として見えてきます。
