オブジェクト

【TypeScript】オプショナルチェイニングについて解説

unit-code@wp-admin

こんにちは、めんだこです!

今回は、TypeScriptのオプショナルチェイニングについて解説していきます。

前提の知識となる、オブジェクトのプロパティへのアクセスと、オプショナルプロパティに関する解説も行なっておりますので、ぜひこちらと合わせてご覧ください。

オプショナルチェイニングとは

まずは、オブジェクトのプロパティにアクセスする方法を確認しましょう。

const obj = {
	prop: "value",
};

console.log(obj.prop); // value

では、次のような場合はどうでしょうか。

type ObjType = {
	prop: string;
};

function printProp(obj: ObjType | null | undefined) {
	console.log(obj.prop);
}

関数の引数の型に、nullとundefinedを追加しました。

このような場合、printProp関数内のobjの中身がない可能性があるため、次のようなコンパイルエラーが発生します。

TSError: ⨯ Unable to compile TypeScript:
'obj' is possibly 'null' or 'undefined'.

このような場合に必要になってくるのが、オプショナルチェイニングです。

先ほどの関数は、次のように書き換えることでエラーは解消されます。

function printProp(obj: ObjType | null | undefined) {
	console.log(obj?.prop);
}

この「.?」の部分がオプショナルチェイニングの構文です。

オプショナルチェイニングとは、簡単に言えば

アクセス元のオブジェクトが存在したらプロパティにアクセスするが、『undefinedかnull』だったらアクセスしないでundefinedを返す

ための構文です。

先ほどの関数を実行してみます。

type ObjType = {
	prop: string;
};

function printProp(obj: ObjType | null | undefined) {
	console.log(obj?.prop);
}

const obj: ObjType = {
	prop: "value",
};

// 実行
printProp(obj); // value
printProp(null); // undefined
printProp(undefined); // undefined

オブジェクトのオプショナルプロパティを扱っている場合などにも頻出しますので、ぜひここで学んでいきましょう。

コラム ブラケット記法でのオプショナルプロパティ

先ほどは、ドット記法での解説をしましたが、ブラケット記法でもオプショナルチェイニングは可能です。

ブラケット記法では、次のように記述します。

obj?.["prop"]

なので、先ほどの例に挙げた関数をブラケット記法で書くと次のようになります。

function printProp(obj: ObjType | undefined | null) {
	console.log(obj?.["prop"]);
}

関数呼び出し時のオプショナルチェイニング

関数の呼び出しの際にも、オプショナルチェイニングは可能です。

こちらの例を見てみましょう。

type User = {
	name: string;
	age: number;
};

type UserFunc = ({ name, age }: User) => User;

function generateUser({ name, age }: User): User {
	return {
		name,
		age,
	};
}

function genAndPrintUser(
	generateUser: UserFunc | null | undefined,
	name: string,
	age: number,
) {
	console.log(generateUser?.({ name, age }));
}

genAndPrintUser(generateUser, "mendako", 25); // { name: 'mendako', age: 25 }
genAndPrintUser(null, "mendako", 25); // undefined
genAndPrintUser(undefined, "mendako", 25); // undefined

ここでは、関数genAndPrintUser内で、genetateUserが返すUserオブジェクトが存在しない場合の、エラーハンドリングとしてオプショナルチェイニングが使われています。

このように、関数呼び出しの際のオプショナルチェイニングは、

func?.()

という形で使われます。

メソッド呼び出し時のオプショナルチェイニング

関数の呼び出しと同様に、オブジェクトのメソッドにもオプショナルチェイニングは活用できます。

とはいえ、通常のオプショナルチェイニングと考え方は変わりません。

class User {
	name: string;
	age: number;

	constructor(name: string, age: number) {
		this.name = name;
		this.age = age;
	}

	isYoung() {
		return this.age < 20;
	}
}

const john = new User("john", 22);

function printIsYoung(user: User | null | undefined) {
	console.log(user?.isYoung()); // メソッド呼び出し時のオプショナルチェイニング
}

printIsYoung(john); // false
printIsYoung(null); // undefined
printIsYoung(undefined); // undefined

まとめ

今回は、オプショナルチェイニングについて解説していきました。

最後にオプショナルチェイニングの考え方について、「プロを目指すためのTypeScript入門」の中の一節を引用して終わりたいと思います。

?.から続く、まとめて飛ばされるひとまとまりの部分をオプショナルチェイン(optional chain)と呼びます。
オプショナルチェインは、プロパティアクセス・関数呼び出し・メソッド呼び出しから成ります。 例えば、次のようなものも1つのオプショナルチェインであり、objがnullやundefinedならまとめて飛ばされます。

obj?.foo[”bar”]().baz().hoge

このような見方をすると、?.はプロパティアクセスの.に類似の構文という一面に加えて、オプショナルチェイン開始の記号という側面も持っていることがわかりますね。

プロを目指す人のためのtypescript入門

参考

こちらの記事の執筆にあたり、以下の書籍を参考・利用させていただきました。

ありがとうございました!

【書籍】

今回は、ご覧いただきありがとうございました。

より良い記事を提供するため、この記事に対するご指摘・ご感想等ございましたら随時コメントを募集しております。
お気軽に書き込みくださいませ。

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


ABOUT ME
めんだこ
めんだこ
webエンジニア

バックエンドの技術を中心に、フロントエンドやインフラ周りの知識も記事にしています!
・プログラミングの学習法や知識
・エンジニアとして考えていること など
を共有して、より良いエンジニアライフを送るための情報を発信します!


新卒未経験でwebエンジニアとなり、翌年からフリーランスとして活動している、現在25歳。
未だにプログラミングが楽しくて仕方ないらしい。
記事URLをコピーしました