TypeScriptにおいて、null
や undefined
といった値を適切に扱わないと、実行時に思わぬエラーが発生することがあります。これらの値は、オブジェクトや変数が未定義の状態を示し、想定外の動作を引き起こすことがあります。特に、プロパティの存在を前提にアクセスしようとすると、TypeError
が発生し、コードの実行が止まってしまいます。こうしたエラーを防ぐために登場したのが、TypeScriptの「オプショナルチェイニング」です。本記事では、このオプショナルチェイニングを使って、null
や undefined
を安全に処理し、コードの信頼性を高める方法について詳しく解説します。
nullやundefinedとは
TypeScriptでは、null
と undefined
はそれぞれ異なる意味を持つ値ですが、どちらも「値が存在しない」状態を表します。
undefinedとは
undefined
は、変数が宣言されているものの、値が割り当てられていない状態を指します。つまり、変数は存在するが、中身は未定義の状態です。以下は undefined
の例です:
let value;
console.log(value); // 出力: undefined
nullとは
null
は、開発者が意図的に「値がない」ことを表すために使用します。つまり、null
は変数に明示的に値が設定されていないことを示します。例を見てみましょう:
let value = null;
console.log(value); // 出力: null
nullとundefinedの違い
null
は「意図的に値がない」状態を示すのに対し、undefined
は「値が割り当てられていない」場合に自動的に発生します。TypeScriptでは、両者は異なるものとして扱われるため、特定の状況では注意が必要です。
nullやundefinedによるエラーのリスク
null
や undefined
を適切に扱わない場合、TypeScriptやJavaScriptの実行時に予期せぬエラーが発生することがあります。特にオブジェクトのプロパティやメソッドにアクセスする際、null
や undefined
が存在すると、TypeError
などの深刻なエラーにつながる可能性があります。
代表的なエラー: TypeError
最もよく見られるエラーは TypeError: Cannot read property '〇〇' of null
または TypeError: Cannot read property '〇〇' of undefined
です。このエラーは、オブジェクトや配列が null
または undefined
であるにもかかわらず、そのプロパティにアクセスしようとした場合に発生します。以下はその例です。
let user = null;
console.log(user.name); // TypeError: Cannot read property 'name' of null
このエラーは、user
が null
であるため、name
プロパティにアクセスできないことが原因です。
エラーが引き起こす影響
null
や undefined
によるエラーが発生すると、スクリプトが途中で停止し、アプリケーション全体がクラッシュする可能性があります。また、これらのエラーはデバッグが難しい場合があり、特に複雑なアプリケーションや非同期処理の中で発生すると、予期せぬバグの原因となります。
エラーを防ぐための基本的なチェック
エラーを防ぐためには、プロパティにアクセスする前に、そのオブジェクトが null
または undefined
でないことを確認する必要があります。従来は次のようなチェックがよく使用されていました:
if (user && user.name) {
console.log(user.name);
}
この方法でもエラーは防げますが、コードが複雑になりやすく、可読性が低下することがあります。ここで、後述するオプショナルチェイニングが非常に役立つのです。
オプショナルチェイニングの概要
オプショナルチェイニング(?.
)は、TypeScript 3.7以降で導入された機能で、null
や undefined
の可能性があるオブジェクトのプロパティやメソッドに安全にアクセスするための構文です。この構文を使用することで、これまで手動で行っていた null
や undefined
のチェックを自動的に行い、コードの簡潔さと可読性が大幅に向上します。
オプショナルチェイニングの基本構文
オプショナルチェイニングを使う場合、通常のプロパティアクセスやメソッド呼び出しに対して ?.
を追加します。もし、そのオブジェクトが null
または undefined
であれば、エラーを発生させることなく自動的に undefined
を返します。以下は基本的な使い方の例です:
let user = null;
console.log(user?.name); // 出力: undefined
この例では、user
が null
であるため、通常ならエラーが発生しますが、オプショナルチェイニングを使うことで、エラーは発生せず、undefined
が返されます。
ネストされたプロパティのアクセス
複雑なオブジェクトに対してもオプショナルチェイニングは有効です。特にネストされたプロパティへのアクセス時に null
や undefined
の可能性がある場合、従来の方法では何度もチェックが必要でしたが、オプショナルチェイニングを使うとコードを簡潔にできます。
let user = { address: null };
console.log(user?.address?.city); // 出力: undefined
この例では、address
が null
であるため、city
にアクセスする前に undefined
が返され、エラーを回避しています。
メソッドの呼び出しにも対応
オプショナルチェイニングは、プロパティアクセスだけでなく、メソッド呼び出しでも使用できます。メソッドが存在しない場合にも安全に処理を行い、エラーを防ぐことができます。
let user = {
greet: null
};
user.greet?.(); // エラーは発生せず、何も実行されない
このように、オプショナルチェイニングは多様な場面で null
や undefined
によるエラーを回避し、開発者が意図する動作を維持します。
オプショナルチェイニングの利便性
オプショナルチェイニングは、null
や undefined
によるエラーを防ぐだけでなく、コードの可読性や保守性を大幅に向上させます。特に、ネストされたオブジェクト構造や、動的にプロパティが追加される可能性のあるデータを扱う際に、その利便性が際立ちます。
コードの簡潔化
従来、null
や undefined
のチェックを行うためには、複数の論理演算子や条件式を使って冗長なコードを書かなければなりませんでした。例えば、以下のようなコードを想像してみてください。
if (user && user.address && user.address.city) {
console.log(user.address.city);
}
このコードは、user
やそのプロパティが存在するかどうかを段階的にチェックしています。オプショナルチェイニングを使用すれば、このチェックを簡潔に書くことができます。
console.log(user?.address?.city);
このように、コードが非常に簡潔かつ読みやすくなり、エラーの可能性も減少します。
ネストされたデータ構造の処理が容易
現代のウェブ開発では、APIから受け取るデータが複雑で、ネストされたオブジェクトや配列を扱うことが頻繁にあります。これらのデータには、時折 null
や undefined
が含まれることがあり、エラーを引き起こしやすいです。オプショナルチェイニングを使うことで、この問題に対処できます。
例えば、以下のようなAPIレスポンスがあるとします:
let response = {
data: {
user: null
}
};
このレスポンスの中に user
オブジェクトが存在しない場合、response.data.user.name
にアクセスするとエラーが発生します。しかし、オプショナルチェイニングを使えば、以下のように安全に処理できます:
console.log(response?.data?.user?.name); // 出力: undefined
これにより、コードがより堅牢になり、データの状態にかかわらず安全に動作します。
エラー処理を容易にする
null
や undefined
の存在を事前にチェックするためのロジックが減るため、エラー処理の分岐が少なくなり、コード全体がシンプルになります。また、エラーが発生する箇所を減らすことで、デバッグが容易になり、アプリケーションの保守性が向上します。
オプショナルチェイニングを使うことで、複雑なオブジェクト構造を扱う際のバグの発生率が低下し、より信頼性の高いコードを作成することができます。
オプショナルチェイニングの具体例
オプショナルチェイニングは、実際にどのように使われるかを具体的なコード例で見ていくと、その利便性が一層理解しやすくなります。ここでは、オブジェクトのプロパティやメソッド、配列の要素に対してオプショナルチェイニングを使う具体的な例を示します。
オブジェクトのプロパティに対するオプショナルチェイニング
まず、基本的なオブジェクトのプロパティアクセスの例です。以下のようなオブジェクトがある場合を考えます:
let user = {
name: "Alice",
address: {
city: "Tokyo"
}
};
もし address
プロパティが存在しない可能性がある場合、オプショナルチェイニングを使って安全に city
にアクセスできます。
console.log(user?.address?.city); // 出力: "Tokyo"
ここで user.address
が存在しなければ、エラーは発生せず undefined
が返されます。
メソッド呼び出しに対するオプショナルチェイニング
次に、オプショナルチェイニングをメソッド呼び出しに使用する例です。以下のように、ユーザーオブジェクトに greet
というメソッドがあるかもしれない場合を考えてみます。
let user = {
name: "Alice",
greet() {
return `Hello, ${this.name}`;
}
};
もし greet
メソッドが存在する場合だけ呼び出したい場合、オプショナルチェイニングを使用します。
console.log(user?.greet?.()); // 出力: "Hello, Alice"
この例では、greet
メソッドが存在しない場合でもエラーが発生せず、undefined
が返されます。
配列要素に対するオプショナルチェイニング
オプショナルチェイニングは、配列の要素にアクセスする際にも使えます。例えば、次のようなネストされた配列がある場合を考えます。
let users = [
{ name: "Alice", age: 25 },
{ name: "Bob", age: 30 }
];
もし、配列内の特定のインデックスに要素が存在しない場合でも、安全にアクセスできます。
console.log(users?.[2]?.name); // 出力: undefined
ここでは、users[2]
が存在しないため、エラーは発生せず、undefined
が返されます。
動的に変化するデータに対するオプショナルチェイニング
APIから動的に受け取るデータや、構造が変更される可能性があるデータに対しても、オプショナルチェイニングは非常に有効です。以下は、動的に変化するデータの例です:
let response = {
data: {
user: {
profile: {
age: 25
}
}
}
};
このような場合、profile
が存在するかどうかをチェックしつつ、age
にアクセスできます。
console.log(response?.data?.user?.profile?.age); // 出力: 25
これにより、ネストされたプロパティが途中で null
や undefined
である場合にも、エラーを回避しつつ安全に値を取得できます。
これらの例からわかるように、オプショナルチェイニングは様々な場面で null
や undefined
によるエラーを回避し、コードの信頼性を高めるのに役立ちます。
オプショナルチェイニングと論理演算子の比較
オプショナルチェイニングを使うと、従来の &&
論理演算子を使った null
や undefined
チェックと比べて、コードがよりシンプルかつ読みやすくなります。ここでは、従来の論理演算子による方法とオプショナルチェイニングの比較を行い、その違いと利便性について解説します。
従来の論理演算子によるチェック
TypeScriptやJavaScriptでは、オブジェクトが null
または undefined
かを確認するために、よく &&
(論理積)を使います。この方法では、各プロパティが存在するかを逐次確認する必要があります。
例えば、以下のようなネストされたオブジェクトにアクセスする場合:
let user = {
name: "Alice",
address: {
city: "Tokyo"
}
};
address
が存在しない可能性がある場合、論理演算子を使ったコードは次のようになります:
console.log(user && user.address && user.address.city); // 出力: "Tokyo"
このコードは、オブジェクトが null
や undefined
でないことを一段階ずつ確認するため、冗長になりがちです。また、プロパティの数が増えるほど、コードが長くなり、可読性が低下します。
オプショナルチェイニングを使った簡略化
同じ処理をオプショナルチェイニングを使って書くと、コードは非常に簡潔になります:
console.log(user?.address?.city); // 出力: "Tokyo"
このコードでは、user
や address
が存在する場合のみ city
にアクセスします。もし user
や address
が null
または undefined
であれば、エラーを発生させることなく undefined
を返します。これにより、エラー処理のための冗長なコードを減らし、コードが見やすくなります。
メソッド呼び出し時の比較
メソッド呼び出し時にも、従来の論理演算子とオプショナルチェイニングを比較することができます。たとえば、以下のように、メソッドが存在しない場合に備えてチェックする必要がある場合:
let user = {
greet: function() {
return "Hello!";
}
};
// 論理演算子によるチェック
console.log(user && user.greet && user.greet()); // 出力: "Hello!"
このコードでは、user
や greet
メソッドが存在するかを確認しています。これをオプショナルチェイニングを使うと次のように簡単になります:
console.log(user?.greet?.()); // 出力: "Hello!"
メソッドが存在しない場合にもエラーが発生せず、処理がスムーズに進みます。
論理演算子とオプショナルチェイニングの違い
- 論理演算子 (
&&
): 全てのステップでnull
またはundefined
のチェックを手動で行う必要があります。コードが冗長になりやすいです。 - オプショナルチェイニング (
?.
): 自動的にnull
やundefined
のチェックを行い、エラーを発生させません。より簡潔で可読性が高いコードが書けます。
オプショナルチェイニングは、特にネストされたプロパティやメソッドにアクセスする際のコードを大幅に簡略化でき、従来の論理演算子に比べて使い勝手が良くなります。これにより、コードが短くなり、可読性が向上するため、開発者にとって効率的なツールとなります。
オプショナルチェイニングの限界と注意点
オプショナルチェイニングは非常に便利でコードの簡潔化に役立つツールですが、すべての状況に万能というわけではありません。使い方を誤ると、意図した動作が得られない場合や、バグを引き起こす可能性があります。ここでは、オプショナルチェイニングの限界や注意点について解説します。
オプショナルチェイニングの限界
デフォルト値が必要な場合
オプショナルチェイニングは、null
または undefined
の場合にエラーを回避するために undefined
を返します。しかし、undefined
をそのまま返すのではなく、特定のデフォルト値を返したい場合には、オプショナルチェイニングだけでは不十分です。このような場合は、??
(Nullish coalescing operator: null合体演算子)を併用します。
let user = null;
console.log(user?.name ?? "デフォルト名"); // 出力: "デフォルト名"
この例では、user?.name
が undefined
または null
の場合に、デフォルト値として "デフォルト名"
が返されます。
書き込み操作には使用できない
オプショナルチェイニングは、読み取り時には非常に便利ですが、書き込み操作には使用できません。次のようなコードは無効です。
user?.name = "Alice"; // エラー:オプショナルチェイニングによる書き込みは無効
これは、オプショナルチェイニングはあくまで「値が存在するかを確認する」ための機能であり、プロパティの設定や変更には使用できないためです。この場合、オブジェクトが null
でないことを明示的に確認した上で、プロパティに値を代入する必要があります。
非存在のプロパティに対する過信
オプショナルチェイニングは、プロパティが存在しない場合に undefined
を返すため、意図せず間違ったプロパティにアクセスしても気づかないリスクがあります。例えば、タイプミスによって誤ったプロパティにアクセスした場合でもエラーにならないため、デバッグが難しくなることがあります。
let user = { name: "Alice" };
console.log(user?.names); // 出力: undefined(エラーが発生しない)
この例では、正しいプロパティ名は name
ですが、タイプミスで names
としてしまった場合でもエラーが発生しないため、バグを見逃しやすくなります。
パフォーマンスの問題
オプショナルチェイニングはコードを簡潔にしますが、多用しすぎるとパフォーマンスに悪影響を及ぼす可能性があります。特に、頻繁に実行されるコードや、パフォーマンスが重要な部分で過度にオプショナルチェイニングを使用する場合は、注意が必要です。
例えば、次のような深いネストされたオブジェクトに対して何度もオプショナルチェイニングを使う場合、毎回のチェックに追加のオーバーヘッドが発生します。
let data = { user: { profile: { address: { city: "Tokyo" } } } };
console.log(data?.user?.profile?.address?.city); // パフォーマンスに影響する場合がある
このような場合、最適化を考える必要があります。
意図しないスキップ
オプショナルチェイニングは、null
や undefined
を避けるために使われますが、場合によっては値が null
または undefined
であることが意図的で、それを検出してエラー処理を行いたいケースもあります。オプショナルチェイニングを使うと、それらのケースをスキップしてしまう可能性があります。
let user = { name: null };
console.log(user?.name); // 出力: null(エラーは発生しないが、意図的なnullを見逃す可能性)
この場合、name
が null
であることを問題として処理したい場合、オプショナルチェイニングを使用することが適切ではないかもしれません。
まとめ
オプショナルチェイニングは非常に便利でコードを簡潔に保つ手段ですが、使用する際にはいくつかの限界や注意点を考慮する必要があります。特に、デフォルト値を設定する場合や、書き込み操作、パフォーマンスの問題には気をつける必要があります。適切な場面で使うことで、その利便性を最大限に活用できます。
TypeScriptにおける他のnull対策
TypeScriptでは、null
や undefined
によるエラーを回避するために、オプショナルチェイニング以外にもいくつかの方法が用意されています。これらの方法を適切に活用することで、より堅牢でエラーの少ないコードを書くことができます。ここでは、他の主要な null
対策を紹介します。
Nullish Coalescing Operator (??)
Nullish Coalescing Operator(??
)は、null
または undefined
の場合にデフォルト値を設定するための演算子です。この演算子を使うと、null
や undefined
に対して安全にデフォルト値を返すことができます。
例えば、次のようなコードがあります:
let name = null;
console.log(name ?? "デフォルト名"); // 出力: "デフォルト名"
name
が null
なので、"デフォルト名"
が返されます。これにより、null
や undefined
の場合に適切なデフォルト値を設定できるため、実行時エラーを防ぐことができます。
型ガード
TypeScriptでは、型ガードを使って特定の型に基づいて条件を分岐させることができます。これにより、null
や undefined
であるかどうかを明示的にチェックして安全に処理することができます。
以下の例では、null
かどうかをチェックしてから処理を行うコードです:
function greet(user: string | null) {
if (user !== null) {
console.log(`Hello, ${user}`);
} else {
console.log("Hello, Guest");
}
}
greet("Alice"); // 出力: Hello, Alice
greet(null); // 出力: Hello, Guest
このように、型ガードを使って null
でないことを確認した後にプロパティやメソッドにアクセスすることで、予期せぬエラーを防ぐことができます。
Non-Null Assertion Operator (!)
非Nullアサーション演算子(!
)は、開発者が「この値は絶対に null
や undefined
ではない」と保証する場合に使用されます。TypeScriptはこの演算子を使うと、その変数が null
や undefined
ではないと仮定して処理を続行します。
以下はその例です:
let user: string | undefined = "Alice";
console.log(user!.toUpperCase()); // 出力: "ALICE"
この例では、user!
を使って、user
が undefined
でないことを明示的に示しています。ただし、もし user
が実際には undefined
だった場合、実行時にエラーが発生します。したがって、非Nullアサーション演算子の使用は慎重に行うべきです。
Strict Null Checks
TypeScriptのtsconfig.json
でstrictNullChecks
オプションを有効にすると、null
や undefined
に対してより厳密な型チェックが行われます。これにより、意図しない null
や undefined
の使用を事前に防ぐことができます。
strictNullChecks
が有効になると、null
や undefined
は明示的に許可されていない限り、他の型と混在できなくなります。例えば、以下のように変数の型が厳密にチェックされます:
let user: string = "Alice";
user = null; // エラー: Type 'null' is not assignable to type 'string'.
この設定を有効にすることで、null
や undefined
によるバグを未然に防ぐことができ、より安全なコードが書けるようになります。
Optional ParametersとDefault Parameters
関数にオプショナルなパラメータを指定することで、null
や undefined
のチェックを軽減することができます。TypeScriptでは、オプショナルパラメータに対してデフォルト値を設定することも可能です。これにより、関数にパラメータが渡されなかった場合にも安全にデフォルト値が使用されます。
function greet(user: string = "Guest") {
console.log(`Hello, ${user}`);
}
greet(); // 出力: Hello, Guest
greet("Alice"); // 出力: Hello, Alice
このように、デフォルト値を指定することで、null
や undefined
の問題を避けつつ、より簡潔なコードを書くことができます。
まとめ
TypeScriptには、オプショナルチェイニング以外にも null
や undefined
によるエラーを回避するさまざまな手段があります。Nullish Coalescing Operator、型ガード、非Nullアサーション、strictNullChecks などの機能を適切に組み合わせることで、より堅牢で安全なコードを書くことが可能です。それぞれの対策を理解し、適切に使い分けることが重要です。
オプショナルチェイニングを使った実践的な例
オプショナルチェイニングは、APIレスポンスやユーザー入力など、不確実なデータを扱う際に非常に役立ちます。ここでは、オプショナルチェイニングを活用した実践的な例を通じて、どのように現実のプロジェクトでエラーを防ぎながらコードの品質を向上させるかを紹介します。
例1: APIレスポンスの処理
APIからのレスポンスデータはしばしば不確実で、必要なデータが欠けていることがあります。このような場合にオプショナルチェイニングを使えば、安全にデータを取得し、エラーを防ぐことができます。次の例では、APIからのユーザーデータを処理します。
interface User {
id: number;
profile?: {
name?: string;
address?: {
city?: string;
zipcode?: string;
};
};
}
const fetchUserData = async (userId: number): Promise<User> => {
// 仮想的なAPIリクエスト
return await fetch(`https://example.com/users/${userId}`).then(res => res.json());
};
const displayUserInfo = async (userId: number) => {
const user = await fetchUserData(userId);
// オプショナルチェイニングを使用して安全にデータにアクセス
console.log(`Name: ${user.profile?.name ?? "名前が未登録です"}`);
console.log(`City: ${user.profile?.address?.city ?? "住所が未登録です"}`);
};
displayUserInfo(123);
このコードでは、profile
や address
が null
または undefined
の場合にエラーを回避し、デフォルトメッセージを表示します。これにより、APIからのレスポンスデータが完全でなくても安全に処理が行えます。
例2: 動的なフォームデータの処理
ウェブアプリケーションでのユーザーフォームでは、動的に入力されるデータに対してオプショナルチェイニングを使用することで、未入力のフィールドに対するエラーを回避できます。次の例では、動的に生成されるフォームデータを処理します。
interface FormData {
personalInfo?: {
firstName?: string;
lastName?: string;
};
contactInfo?: {
email?: string;
phone?: string;
};
}
const processFormData = (formData: FormData) => {
const firstName = formData.personalInfo?.firstName ?? "不明";
const lastName = formData.personalInfo?.lastName ?? "不明";
const email = formData.contactInfo?.email ?? "未登録";
const phone = formData.contactInfo?.phone ?? "未登録";
console.log(`名前: ${firstName} ${lastName}`);
console.log(`メール: ${email}`);
console.log(`電話番号: ${phone}`);
};
const submittedData: FormData = {
personalInfo: {
firstName: "太郎"
}
};
processFormData(submittedData);
この例では、personalInfo
と contactInfo
が未定義の場合でも、オプショナルチェイニングと ??
演算子を使用して、デフォルトの値を表示することができます。フォームが部分的にしか入力されていなくても、エラーを回避し、システムがスムーズに動作します。
例3: 配列の安全なアクセス
配列の要素にアクセスする際、配列のインデックスが範囲外の場合にエラーが発生することを防ぐためにも、オプショナルチェイニングが役立ちます。次の例では、APIから受け取ったユーザーデータをリスト形式で表示しますが、データが不足している可能性がある場合でも安全にアクセスします。
const users = [
{ name: "Alice", age: 30 },
{ name: "Bob" },
];
const displayUserList = (userList: { name: string; age?: number }[]) => {
userList.forEach((user, index) => {
console.log(`ユーザー${index + 1}: 名前: ${user.name}, 年齢: ${user.age?.toString() ?? "不明"}`);
});
};
displayUserList(users);
このコードでは、配列内のユーザーに age
プロパティが存在しない場合にも undefined
が返されず、代わりに "不明"
が表示されるようになっています。これにより、データの不整合や欠損を防ぎつつ、実行時エラーを避けることができます。
例4: ネストされたオブジェクトの処理
オプショナルチェイニングは、ネストされたオブジェクトを処理する際にも非常に便利です。例えば、ユーザー情報が深くネストされている場合でも、エラーを発生させずにアクセスすることができます。
interface UserData {
settings?: {
preferences?: {
theme?: string;
notificationsEnabled?: boolean;
};
};
}
const userSettings: UserData = {
settings: {
preferences: {
theme: "dark",
}
}
};
const displayUserSettings = (user: UserData) => {
const theme = user.settings?.preferences?.theme ?? "デフォルトテーマ";
const notifications = user.settings?.preferences?.notificationsEnabled ?? false;
console.log(`テーマ: ${theme}`);
console.log(`通知: ${notifications ? "有効" : "無効"}`);
};
displayUserSettings(userSettings);
この例では、ユーザーの設定情報が深くネストされている場合でも、オプショナルチェイニングを使用して安全にプロパティにアクセスし、デフォルト値を表示することができます。
まとめ
オプショナルチェイニングは、複雑なデータ構造や不確実なデータを扱う際に非常に役立ちます。実際の開発シナリオでこの機能を活用することで、コードの安全性と信頼性が向上し、実行時エラーを防ぐことが可能です。
演習問題: オプショナルチェイニングの適用
ここでは、オプショナルチェイニングの理解を深めるための演習問題を用意しました。これらの問題を通じて、実際にコードを書きながら null
や undefined
の可能性を考慮した安全なコードを書く練習をしましょう。
問題1: ネストされたオブジェクトのプロパティへのアクセス
以下のようなユーザーデータのオブジェクトがあります。このオブジェクトには、ユーザーのプロフィールや連絡先情報が含まれていますが、場合によっては一部のデータが存在しないことがあります。このデータを安全にアクセスして、出力するコードを書いてください。
const userData = {
profile: {
name: "John",
contact: {
email: "john@example.com"
}
}
};
要求される出力
- ユーザーの名前 (
profile.name
) が存在する場合は、その名前を表示する。存在しない場合は"名前が未登録です"
と表示する。 - ユーザーのメールアドレス (
profile.contact.email
) が存在する場合は、そのメールアドレスを表示する。存在しない場合は"メールアドレスが未登録です"
と表示する。
解答例
const name = userData.profile?.name ?? "名前が未登録です";
const email = userData.profile?.contact?.email ?? "メールアドレスが未登録です";
console.log(`名前: ${name}`);
console.log(`メールアドレス: ${email}`);
問題2: 配列の要素への安全なアクセス
以下のような商品リストの配列がありますが、配列の要素が不足している場合でもエラーが発生しないように、安全に各商品の名前と価格を表示してください。
const products = [
{ name: "商品A", price: 1000 },
{ name: "商品B" }
];
要求される出力
- 各商品の名前 (
name
) と価格 (price
) を表示する。価格が未登録の場合は"価格不明"
と表示する。
解答例
products.forEach((product, index) => {
const price = product.price?.toString() ?? "価格不明";
console.log(`商品${index + 1}: 名前: ${product.name}, 価格: ${price}`);
});
問題3: メソッドの存在確認
以下のようなオブジェクトがあり、その中に greet
というメソッドが存在する場合のみ呼び出してください。存在しない場合は、何もしないコードを書いてください。
const user = {
name: "Jane",
greet() {
return `Hello, ${this.name}`;
}
};
要求される動作
greet
メソッドが存在する場合のみ実行し、Hello, Jane
を表示する。存在しない場合はエラーを発生させず、何もしない。
解答例
console.log(user.greet?.()); // greetメソッドが存在する場合のみ呼び出す
問題4: デフォルト値の適用
以下のようなオブジェクトがあり、ユーザーの設定情報を取得します。設定情報が存在しない場合や一部の値が未定義の場合に、デフォルト値を適用して出力するコードを書いてください。
const settings = {
theme: "dark",
notificationsEnabled: undefined
};
要求される出力
- テーマ (
theme
) が設定されていればそのテーマを表示し、設定されていなければ"default"
を表示する。 - 通知が有効 (
notificationsEnabled
) であれば"通知: 有効"
、無効または未設定であれば"通知: 無効"
と表示する。
解答例
const theme = settings.theme ?? "default";
const notifications = settings.notificationsEnabled ?? false;
console.log(`テーマ: ${theme}`);
console.log(`通知: ${notifications ? "有効" : "無効"}`);
まとめ
これらの演習問題を通じて、オプショナルチェイニングと null
対策に関する知識を深めることができます。null
や undefined
による実行時エラーを回避し、堅牢で安全なコードを書くための技術をぜひ活用してみてください。
まとめ
本記事では、TypeScriptにおける null
や undefined
を扱う際に非常に便利なオプショナルチェイニングの仕組みと、その具体的な利便性について解説しました。従来の論理演算子を使ったチェックに比べて、オプショナルチェイニングはコードを簡潔にし、エラーを回避しやすくします。また、実践的な例や演習問題を通じて、様々なシナリオでの適用方法も学びました。適切に活用することで、コードの可読性や保守性を向上させ、安全なアプリケーション開発に役立てることができます。
コメント