TypeScript ?. 演算子:null または undefined の可能性がある値に安全にアクセスする方法
TypeScriptにおける ?. 演算子(オプションチェーン演算子)
?. 演算子は、オプションチェーン演算子と呼ばれる演算子で、null または undefined の可能性がある値に対して安全にアクセスするための便利な機能です。
?. 演算子の使い方
?. 演算子は、プロパティやメソッドのチェーン呼び出しにおいて、null または undefined の可能性がある中間オブジェクトを安全に処理するために使用されます。
従来のコードでは、null または undefined の可能性があるオブジェクトに対してプロパティやメソッドにアクセスしようとすると、実行時エラーが発生する可能性がありました。
?. 演算子を使用すると、null または undefined の場合に処理をスキップして、エラーを回避することができます。
const user = {
name: "John Doe",
address: {
city: "Tokyo",
},
};
// 従来のコード
const city = user.address && user.address.city; // エラーが発生する可能性あり
// ?. 演算子の使用
const city = user?.address?.city; // エラーが発生せず、city は undefined になる
console.log(city); // undefined
上記の例では、user.address が null または undefined の場合、従来のコードは実行時エラーが発生します。
一方、?. 演算子を使用すると、エラーが発生せずに city は undefined になります。
?. 演算子を使用する利点は、以下のとおりです。
- コードの安全性を向上させる: null または undefined の可能性があるオブジェクトに対して安全にアクセスできる
- コードの可読性を向上させる: 従来のコードよりも簡潔で分かりやすいコードを書ける
- null または undefined のチェックを省略できる: ?. 演算子が自動的に null または undefined のチェックを行ってくれる
?. 演算子の注意点
?. 演算子を使用する際には、以下の点に注意する必要があります。
- ?. 演算子は、チェーン呼び出しの最後の要素にのみ使用できる
- ?. 演算子は、型ガードとして使用できない
コードの安全性を向上させ、可読性を向上させるために、?. 演算子の使用を検討しましょう。
プロパティへのアクセス
const user = {
name: "John Doe",
age: 30,
address: {
city: "Tokyo",
postalCode: "100-0001",
},
};
// 従来のコード
const city = user.address && user.address.city;
const postalCode = user.address && user.address.postalCode;
// ?. 演算子の使用
const city = user?.address?.city;
const postalCode = user?.address?.postalCode;
console.log(city); // "Tokyo"
console.log(postalCode); // "100-0001"
一方、?. 演算子を使用すると、エラーが発生せずに city と postalCode はそれぞれ "Tokyo" と "100-0001" になります。
メソッドの呼び出し
const user = {
name: "John Doe",
age: 30,
greet() {
console.log(`Hello, my name is ${this.name}`);
},
};
// 従来のコード
const greeting = user.greet && user.greet();
// ?. 演算子の使用
const greeting = user?.greet?.();
greeting; // "Hello, my name is John Doe"
一方、?. 演算子を使用すると、エラーが発生せずに greeting は "Hello, my name is John Doe" になります。
ネストされたオブジェクトへのアクセス
const data = {
user: {
name: "John Doe",
age: 30,
address: {
city: "Tokyo",
postalCode: "100-0001",
},
},
};
// 従来のコード
const city = data.user && data.user.address && data.user.address.city;
const postalCode = data.user && data.user.address && data.user.address.postalCode;
// ?. 演算子の使用
const city = data?.user?.address?.city;
const postalCode = data?.user?.address?.postalCode;
console.log(city); // "Tokyo"
console.log(postalCode); // "100-0001"
オプションの型ガード
function getUserInfo(userId: number): User | undefined {
// ...
}
const user = getUserInfo(123);
// 従来のコード
if (user) {
console.log(user.name); // エラーが発生する可能性あり
}
// ?. 演算子の使用
if (user?.name) {
console.log(user.name); // エラーが発生しない
}
?. 演算子の代替方法
従来の null チェック
const user = {
name: "John Doe",
age: 30,
address: {
city: "Tokyo",
postalCode: "100-0001",
},
};
// 従来の null チェック
const city = user.address && user.address.city;
const postalCode = user.address && user.address.postalCode;
console.log(city); // "Tokyo"
console.log(postalCode); // "100-0001"
上記の例では、従来の null チェックを使用して、null または undefined の可能性がある値に対して安全にアクセスしています。
ただし、この方法はコードが冗長になり、可読性が低下する可能性があります。
オプション型
type Address = {
city: string;
postalCode: string;
};
type User = {
name: string;
age: number;
address?: Address; // オプション型
};
const user: User = {
name: "John Doe",
age: 30,
};
// オプション型の使用
const city = user.address?.city;
const postalCode = user.address?.postalCode;
console.log(city); // undefined
console.log(postalCode); // undefined
オプション型を使用すると、コードの可読性を向上させることができます。
ただし、オプション型は TypeScript 2.0 以降でしか使用できません。
型ガード
function getUserInfo(userId: number): User | undefined {
// ...
}
const user = getUserInfo(123);
// 型ガード
if (user && "name" in user) {
console.log(user.name); // エラーが発生しない
}
ただし、状況によっては、他の方法がより適切な場合もあります。
上記で紹介した方法を参考に、状況に応じて適切な方法を選択してください。
typescript