TypeScriptでプロパティのOptional(省略可能)とReadonly(読み取り専用)の使い方について、実践的な例を交えながら解説します。
Optionalプロパティ(省略可能なプロパティ)
Optionalプロパティは、そのプロパティが必須ではないことを示します。プロパティ名の後に`?`を付けることで指定できます。
interface User {
name: string; // 必須
age?: number; // 省略可能
email?: string; // 省略可能
}
// 正常に動作する例
const user1: User = {
name: "John"
// age と email は省略可能なので指定しなくてもOK
};
const user2: User = {
name: "Alice",
age: 25,
email: "alice@example.com"
};Readonlyプロパティ(読み取り専用プロパティ)
Readonlyプロパティは、一度値を設定すると変更できないプロパティを定義します。`readonly`キーワードを使用します。
interface Config {
readonly apiKey: string;
readonly baseUrl: string;
timeout?: number;
}
const config: Config = {
apiKey: "abc123",
baseUrl: "https://api.example.com"
};
// エラー: readonly プロパティは変更できない
// config.apiKey = "xyz789";Optional と Readonly の組み合わせ
OptionalとReadonlyは組み合わせて使用することもできます:
interface Settings {
readonly id: number;
readonly name: string;
readonly description?: string; // 省略可能かつ読み取り専用
}
const settings: Settings = {
id: 1,
name: "Default Settings"
};ユースケース
フォームデータの型定義
interface FormData {
username: string; // 必須
password: string; // 必須
readonly id?: string; // 自動生成されるID(省略可能・読み取り専用)
phoneNumber?: string; // 省略可能な電話番号
}APIレスポンスの型定義
interface APIResponse {
readonly status: number; // HTTPステータスコード
readonly data: object; // レスポンスデータ
readonly timestamp?: number; // タイムスタンプ(省略可能)
}注意点と技術的な詳細
1. Readonlyは浅い(shallow)イミュータビリティのみを提供します:
interface NestedObject {
readonly user: {
name: string;
age: number;
}
}
const obj: NestedObject = {
user: { name: "John", age: 30 }
};
// これはエラーにならない(ネストされたオブジェクトは変更可能)
obj.user.name = "Jane";
// これはエラーになる(トップレベルのプロパティは変更不可)
// obj.user = { name: "Jane", age: 25 };2. 型アサーションとの併用:
interface ReadonlyUser {
readonly id: number;
readonly name: string;
}
// as constを使用して、オブジェクトリテラルを完全な読み取り専用にする
const user = {
id: 1,
name: "John"
} as const;これらの機能を適切に使用することで、より堅牢なTypeScriptコードを書くことができます。Optionalプロパティは柔軟性を提供し、Readonlyプロパティはイミュータビリティを確保するのに役立ちます。
まとめ
- `?`を使用してOptionalプロパティを定義
- `readonly`キーワードでReadonlyプロパティを定義
- 両者は組み合わせて使用可能
- Readonlyは浅いイミュータビリティのみを提供
- 適切な使用でコードの安全性と柔軟性が向上
これらの機能を活用することで、型安全性が高く、メンテナンス性の良いTypeScriptコードを書くことができます。