【初心者向け】TypeScriptでオブジェクトを安全に扱う:非nullオブジェクトと分解代入
TypeScriptにおける非nullオブジェクトの分解代入
TypeScriptにおける非nullオブジェクトの分解代入は、ES2015(JavaScript 6)で導入された機能をTypeScriptで安全に利用するための構文です。オブジェクトのプロパティを明示的に取り出し、変数に代入する際に、nullやundefinedの可能性を考慮したコードを書くことができます。
非nullオブジェクトとは
TypeScriptでは、!
演算子を用いて、変数がnullまたはundefinedではないことを型注釈で明示することができます。例えば、以下のように記述できます。
let name: string | null = "TypeScript";
let newName: string = !name; // 型注釈により、newNameはstring型になる
この例では、name
変数はstring
型またはnull
型ですが、!name
演算子を用いることで、newName
変数に代入される値は必ずstring
型であることが保証されます。
分解代入とは
分解代入は、オブジェクトや配列からプロパティや要素を個別に抽出して、変数に代入する構文です。オブジェクトの分解代入の場合、以下のように記述できます。
const person = { name: "John Doe", age: 30 };
const { name, age } = person;
console.log(name); // "John Doe"
console.log(age); // 30
この例では、person
オブジェクトからname
とage
プロパティを抽出し、それぞれname
とage
変数に代入しています。
非nullオブジェクトの分解代入
非nullオブジェクトの分解代入は、!
演算子と分解代入を組み合わせることで実現できます。以下のように記述できます。
const person: { name: string | null, age: number } | null = { name: null, age: 30 };
if (person) {
const { name, age } = person; // personがnullではないことが保証される
console.log(name); // エラー: nameはstring型のはずだが、nullの可能性がある
console.log(age); // 30
}
この例では、person
変数がnullの可能性があることを考慮して、if
文で囲んでいます。if
文内でperson
がnullではないことが保証されるため、分解代入を用いてname
とage
プロパティを安全に取り出すことができます。
nullチェック省略構文
TypeScript 3.7以降では、nullチェック省略構文を用いて、より簡潔に非nullオブジェクトの分解代入を書くことができます。以下のように記述できます。
const person: { name: string | null, age: number } | null = { name: null, age: 30 };
const { name, age } = person ?? {}; // personがnullの場合は空オブジェクトを代入
console.log(name); // null
console.log(age); // 30
type Person = { name: string | null, age: number };
function greet(person: Person | null) {
const { name, age } = person ?? {}; // personがnullの場合は空オブジェクトを代入
if (name) {
console.log(`Hello, ${name}! You are ${age} years old.`);
} else {
console.log("Invalid person object.");
}
}
const person1: Person = { name: "John Doe", age: 30 };
const person2: Person = null;
greet(person1); // Hello, John Doe! You are 30 years old.
greet(person2); // Invalid person object.
greet
関数内で、nullチェック省略構文を用いてperson
オブジェクトの分解代入を行っています。person
がnullの場合は空オブジェクトを代入するため、name
プロパティがnullであっても、エラーが発生せずにコードを実行することができます。
type Person = { name: string | null, age: number };
function greet(person: Person | null) {
if (person) {
const { name, age } = person!; // personがnullではないことを保証
console.log(`Hello, ${name}! You are ${age} years old.`);
} else {
console.log("Invalid person object.");
}
}
const person1: Person = { name: "John Doe", age: 30 };
const person2: Person = null;
greet(person1); // Hello, John Doe! You are 30 years old.
greet(person2); // Invalid person object.
TypeScript 4.1以降では、オプションプロパティの型注釈を用いて、nullの可能性を考慮した分解代入を行うことができます。以下のように記述できます。
type Person = { name?: string, age: number };
function greet(person: Person | null) {
const { name, age } = person;
console.log(`Hello, ${name ?? "Unknown"}! You are ${age} years old.`);
}
const person1: Person = { age: 30 };
const person2: Person = null;
greet(person1); // Hello, Unknown! You are 30 years old.
greet(person2); // Hello, Unknown! You are 30 years old.
この例では、Person
型というインターフェースを定義し、name
プロパティをオプションプロパティとして定義しています。オプションプロパティは、?
記号を用いて定義します。
greet
関数内で、分解代入の右側に型注釈を記述することで、name
プロパティがnullである可能性を考慮することができます。name ?? "Unknown"
と記述することで、name
がnullの場合は"Unknown"
という文字列を代入します。
型ガードを用いたnullチェック
型ガードを用いて、nullチェックを行い、その後分解代入を行うこともできます。以下のように記述できます。
type Person = { name: string, age: number };
function greet(person: Person | null) {
if (person && typeof person === "object" && "name" in person) {
const { name, age } = person;
console.log(`Hello, ${name}! You are ${age} years old.`);
} else {
console.log("Invalid person object.");
}
}
const person1: Person = { name: "John Doe", age: 30 };
const person2: Person = null;
greet(person1); // Hello, John Doe! You are 30 years old.
greet(person2); // Invalid person object.
この例では、greet
関数内で型ガードを用いて、person
がオブジェクト型であり、name
プロパティが存在することを確認しています。確認が取れた場合のみ、分解代入を実行します。
null許容型を用いた分解代入
type Person = { name: string | null, age: number };
function greet(person?: Person | null) {
const { name, age } = person ?? {};
console.log(`Hello, ${name ?? "Unknown"}! You are ${age} years old.`);
}
const person1: Person = { age: 30 };
const person2: Person = null;
greet(person1); // Hello, Unknown! You are 30 years old.
greet(person2); // Hello, Unknown! You are 30 years old.
上記3つの方法は、それぞれ異なる方法で非nullオブジェクトの分解代入を実現しています。状況に応じて、適切な方法を選択してください。
- null許容型は、nullの可能性を明示的に示すことができ、コード的可読性を向上させることができます。
- 型ガードは、より複雑なnullチェックを行う場合に役立ちます。
- オプションプロパティの型注釈は、TypeScript 4.1以降でのみ使用できます。
typescript object ecmascript-6