本連載の趣旨
本連載は、TypeScriptのアップデートを紹介する連載です。
TypeScriptは、その登場以来、順当にバージョンアップを重ね、現在(原稿執筆時点)5.2が最新となっています。各バージョンアップでは、性能改善に関するアップデートが主なものもあれば、大きな機能追加が施されたものもあります。
本連載では、これらのアップデートの内容のうち、バージョン3から5.2までに施されたものを整理し、テーマごとに紹介していきます。具体的には、以下のテーマを予定しています。
- タプルに関するアップデート
- 型システムに関するアップデート
- 型の絞り込みに関するアップデート
- クラス構文に関するアップデート
- デコレータに関するアップデート
第1回目である今回は、上記テーマに含まれていないもので重要なアップデートを取り上げます。これらは、ひとつのテーマで連載1回分の内容にはならないものを、詰め合わせセットのようにして紹介していきます。
新しい演算子
本連載の最初に紹介するアップデートテーマは、新しい演算子です。
nullエラーを回避するオプショナルチェーン
最初に紹介する演算子は、オプショナルチェーンと呼ばれるもので、?.演算子です。この演算子は、JavaScriptにはES2020で導入された演算子ですが、このプロポーザルがステージ3になったのを見極めて、TypeScriptでは2019年11月にリリースされた3.7で先行導入されています。
この?.演算子は、nullやundefinedに対応するための演算子です。例えば、リスト1のMemberインターフェースで表される型のオブジェクトである変数memberを考えます。
interface Member { name: string; phones?: { phone1: string; phone2: string; } }
このmember変数のnameプロパティにアクセスする以下のコードは、memberがnullやundefinedの場合、エラーとなります。
let name = member.name;
そのため、通常は、リスト2のようなチェックコードを記載します。
let name: string | undefined = undefined; if(member != null && member != undefined) { name = member.name; }
これが、?.演算子を利用すると、リスト3のように簡単に記述できます。
let name = member?.name;
この?.はいくらでも繋げることができます。例えば、memberのphones.phone1プロパティにアクセスする場合、そもそも、phonesプロパティがnull/undefinedの可能性があります。その場合も、リスト4のように記述することで、安全にアクセスできます。
let phone1 = member?.phones?.phone1;
nullの時の値を指定できるnull合体演算子
次に紹介する演算子は、null合体演算子と呼ばれるもので、??演算子です。この演算子は、?.同様に、ES2020に先駆けてTypeScript3.7で導入されたものです。この演算子は、変数がnull/undefinedの場合の値を指定するための演算子です。例えば、リスト5のようなコードです。
const note = member.note ?? "なし";
このコードは、オブジェクトであるmember変数のnoteプロパティへのアクセスコードです。もしこのnoteプロパティがオプション扱いである場合、member.noteは、undefinedの可能性があります。リスト5は、その場合のデフォルト値を「なし」と指定したコードとなります。
新たに追加された3個の複合代入演算子
ES2021で、+=をはじめとする複合代入演算子に、新たに&&=、||=、??=の3個の演算子が追加されました。TypeScriptでは、これらの演算子は、2020年リリースのバージョン4.0で先行導入されています。
これらのうち、&&=と||=は、&&や||の記述からわかる通り、論理演算結果を再代入するものです。例えば、リスト6のようなコードです。なお、rand1とrand2は、0から10までの数値を表すとします。
let boo = rand1 >= 3; // (1) boo &&= rand2 >= 5; // (2)
ここで、もしrand1が10ならば、(1)でbooはtrueを表すことになります。そして、もしrand2が3ならば、(2)の右辺はfalseを表すことになります。では、booはどのような値になるかというと、falseになります。それは、(2)全体が以下のコードと同じであることを考えると理解できます。=の右辺の内容は「true && false」となり、その値がbooに再代入されます。
boo1 = boo1 && rand2 >= 5;
このように、論理演算結果を再代入する演算子が&&=であり、||=も同様に考えることができます。例えば、リスト6の(2)の演算子を||=に置き換えた以下の場合、先の例と同様に、rand1が10、rand2が3ならば、booはtrueとなります。
boo ||= rand2 >= 5;
これらの論理演算結果の再代入とは考え方は違いますが、同時期に導入されたのが残りの??=であり、これは、前項で紹介したnull合体演算子の再代入です。例えば名前を表す変数nameがあるとして、以下のコードを記載したとします。これは、nameがnull/undefinedの場合、nameに「名無し」を代入するコードです。
name = name ?? "名無し";
これを簡単に記述できるようにしたのが、??=です(リスト7)。
name ??= "名無し";