TypeScriptのオプショナルプロパティは、プロパティ名の後に疑問符(?)で示されます。これは、プロパティがオブジェクトに存在する場合もあれば、欠如している場合もあることを意味します。これは、すべてのフィールドが必須でない構造を説明する際に便利です。
例:
interface User { id: number; name?: string; } const u1: User = { id: 1 }; // OK const u2: User = { id: 2, name: 'イワン' }; // OK
注意点:
undefinedであるだけでなく、オブジェクトに完全に存在しない場合もあります。if (user.name))は、undefinedと欠如を区別しません。undefinedである可能性を考慮せずに、チェックなしでメソッド/プロパティにアクセスすることです。自分を守るためには:
undefinedのチェックを使用してください:if (user.name !== undefined) { console.log(user.name.toUpperCase()); }
console.log(user.name?.toUpperCase());
オブジェクトのインターフェースが
{ foo?: string }として定義されている場合、プロパティfooは常に文字列またはundefinedのどちらかである必要がありますか?例えば、nullの値を代入することは可能ですか?
間違った答え:
undefinedのいずれかであり、他のものはダメです。"正しい答え:
nullを代入することはTypeScriptが許可しますが、それは型がstring | nullに拡張されている場合のみです。デフォルトでは、stringまたはundefinedのみです。interface A { foo?: string } let x: A = { foo: null }; // エラー!
物語
大規模プロジェクトで、サーバーから送信される一部のオブジェクトが一部のオプショナルフィールドを欠いていました。プログラマーはこれらのプロパティのメソッドを直接呼び出し(例えば、toLowerCase())、フィールドが存在しない場合にruntimeエラーを引き起こしました。問題を解決するために、チームはオプショナルフィールドへのアクセスに厳格なチェックとリントルールを導入しました。
物語
論理式でプロパティの存在とその真偽を混同しました:if (user.email)は空の文字列に対して動作せず、プロパティは設定されていました。これにより、特定の通知がユーザーに送信されないバグが発生しました。
物語
チームはオプショナルプロパティにnullの値を代入することを正しいと考えました。TypeScriptはエラーを出し、これを回避するために型をstring | nullに拡張する必要があり、これによりこれらのオブジェクトに対するビジネスロジック全体の見直しが必要になりました。