はじめに
6年くらい、PythonとPHP中心に活動してましたが、最近TypeScriptの開発も副業でアサインさせていただき、勉強した内容の備忘録を記載させていただきます。
型安全性: ! と ? 演算子について
TypeScriptは、JavaScriptに型安全性を提供し、開発者が実行時のエラーを防ぎ、より信頼性の高いコードを書くことを可能にします。特に、null や undefined の値を扱う際に役立つ2つの重要な演算子が、非nullアサーション演算子(!)とオプショナルチェーン演算子(?.)です。この記事では、info.user!.name と info.user?.email という例を使って、これらの演算子がどのように機能するのか、また値が undefined や null だった場合のについて記載します。
非nullアサーション演算子 (!)
非nullアサーション演算子 (!) は、特定の変数が null または undefined ではないと確信している場合に使用します。この演算子を使うことで、TypeScriptに対して「この値は必ず存在する」と伝え、型チェックをバイパスすることができます。
const info = getUserInfo(); // info.user は null または undefined の可能性がある
const userName = info.user!.name;
この例では、info.user!.name という記述により、info.user が null や undefined でないことを保証しています。これにより、TypeScriptはエラーを出さずに name プロパティにアクセスできるようになります。
info.user が null または undefined だった場合の動作
もし info.user が実際には null または undefined であった場合、このコードは実行時エラーを引き起こします。具体的には、「undefined のプロパティ ‘name’ を読み取ることができません」というエラーが発生し、アプリケーションがクラッシュする可能性があります。
function getUserInfo(): { user?: { name: string } } {
return { user: undefined }; // user が undefined であることをシミュレート
}
const info = getUserInfo();
const userName = info.user!.name; // 実行時エラー: Cannot read property 'name' of undefined
info.user!.name を使うべき場合
- info.user が確実に null や undefined ではないと確信している場合。
- TypeScriptの型推論が、info.user が非nullであることを認識できないが、プログラムのロジック上、安全であると分かっている場合。
オプショナルチェーン演算子 (?.)
オプショナルチェーン演算子 (?.) は、null または undefined である可能性のあるオブジェクトのプロパティに安全にアクセスするための演算子です。この演算子を使うことで、オブジェクトが存在しない場合でもエラーを発生させることなく処理を進めることができます。
const info = getUserInfo(); // info.user は null または undefined の可能性がある
const userEmail = info.user?.email;
この場合、info.user?.email は「info.user が存在する場合は email を返し、存在しない場合は undefined を返す」という意味になります。
info.user が null または undefined だった場合の動作:
もし info.user が null または undefined であれば、info.user?.email の式は undefined を返し、エラーは発生しません。これにより、アプリケーションがクラッシュすることなく、コードは安全に動作します。
function getUserInfo(): { user?: { email: string } } {
return { user: undefined }; // user が undefined であることをシミュレート
}
const info = getUserInfo();
const userEmail = info.user?.email; // undefined を返し、エラーは発生しない
console.log(userEmail); // 出力: undefined
- info.user が null または undefined である可能性があり、その場合でも安全に処理を行いたい場合。
- null または undefined の値が存在する可能性がある状況で、実行時のクラッシュを避けたい場合。
まとめ
1. 安全性と保証:
- info.user!.name は、info.user が常に存在することを前提にしており、型安全性チェックを無視します。
- info.user?.email は、info.user が存在しない場合でも安全に処理を行うため、より安全なにあたいが存在しない場合の対処ができます。
2. エラーハンドリング:
- info.user!.name は、info.user が null または undefined であれば、実行時エラーを引き起こします。
- info.user?.email は、info.user が null または undefined であれば、undefined を返してエラーを回避します。
3. 想定される使用ケース:
- info.user!.name は、info.user が常に存在すると確信している場合に使用します。
- info.user?.email は、info.user が存在しない可能性がある状況でも安全に処理したい場合に使用します。