HTML5テクニカルノート
TypeScriptハンドブック 06: nullとundefinedなど
- ID: FN2106001
- Technique: ECMAScript 2015
- Package: TypeScript 4.2
TypeScript公式「Handbook」の「Everyday Types」から最後にご紹介するのは、おもにnull
とundefined
に関わる項目です(かっこ内は原文の項目タイトル)。そして、その他として若干の説明を補っています。
01 nullとundefined
JavaScriptのプリミティブには、用いることのできる値がないことを示すnull
と、初期化されていない値を意味するundefined
があります。TypeScriptが備えるこれらに対する型は、同じ名前のnull
とundefined
です。ふたつの型がどう扱われるかは、tsconfig.json
のstrictNullChecks
の設定によって変わります。
ノート01■TSConfigのstrictフラグ
tsconfig.json
のstrict
をtrue
にすると、すべての厳格な(strict)モードが有効になります。つまり、strictNullChecks
をtrue
にした効果が得られるということです。
01-01 strictNullChecksがfalseのとき
strictNullChecks
はfalse
がデフォルトです。この場合、null
とundefined
は、すべての型に値として代入できます。
let greeting = "Hello"; greeting = null; // OK greeting = undefined; // OK
けれど、予め定めたのとは異なる値が入ると、バグの原因になりかねません。とくに、オブジェクトの参照が取得できずにnull
となった場合、プロパティやメソッドを参照すればランタイムエラーになってしまいます。とくに必要性がないなら、strictNullChecks
はtrue
にするのがよいでしょう。
const item = document.getElementById("item"); // 要素の参照が取得できない場合 item.textContent = "item 01"; // コンパイルエラーなし // ランタイムエラー: Uncaught TypeError: Cannot set property 'textContent' of null
01-02 strictNullChecksがtrueのとき
strictNullChecks
をtrue
に定めると、null
やundefined
が型づけに含まれないかぎり、これらの値は受け入れられません。
let greeting = "Hello"; // 型 'null' を型 'string' に割り当てることはできません。 greeting = null; // 型 'undefined' を型 'string' に割り当てることはできません。 greeting = undefined;
null
やundefined
が受け取れるようにするには、ユニオン型ではっきりとnull
またはundefined
を加えてください。その場合、null
とundefined
とは型が区別されます。
let greetingWithNull: string | null = "Howdy"; greetingWithNull = null; // OK // 型 'undefined' を型 'string | null' に割り当てることはできません。 greetingWithNull = undefined;
取り出したオブジェクトの参照がnull
かもしれない場合には、そのままプロパティやメソッドにアクセスすることは許されません。コンパイルエラーが示されます。
const item = document.getElementById("item"); // コンパイルエラー: オブジェクトは 'null' である可能性があります。 item.textContent = "item 01";
エラーを避けるには、プロパティやメソッドにアクセスする前に、オブジェクトが取り出せたことを確かめてください。これで、ランタイムでもエラーが起こりることはありません。
if (item) { // オブジェクトの存在を確認 item.textContent = "item 01"; }
01-03 非nullアサーション演算子!
null
やundefined
でないかの判定を、型アサーションの構文で省くこともできます。用いるのは、非null
アサーション演算子!
です。式の後に!
演算子を添えると、値がnull
でもundefined
でもないことを型アサーションします。
const item = document.getElementById("item"); item!.textContent = "item 01"; // コンパイルエラーなし
けれど、型アサーションはデータを変換する訳ではありません。TypeScriptに、値がnull
やundefined
となり得るかの分析を止めさせるだけです。オブジェクトの参照が得られなかったのにプロパティやメソッドにアクセスすれば、ランタイムエラーになってしまいます。
02 その他
今のところは存在だけ覚えておけばよい型を、いくつかご紹介します。
02-01 列挙型(enum)
列挙型(enum
)は、TypeScriptがJavaScriptに加えた機能で、列挙した名前の低数値をまとめたデータです。TypeScriptの他の機能と異なり、JavaScriptに型を定めただけでなく、言語とランタイムの拡張になります。列挙型について理解するまでは、こういう型があることだけ覚えておけば構いません。列挙型について詳しくは、リファレンスの「Enums」をご参照ください。
02-02 あまり一般的でないプリミティブ
TypeScriptの型システムにおいて、あまり一般的でないJavaScriptのプリミティブをふたつ簡単にご説明します。
bigInt型
BigInt
のデータは、 数値(number
)型プリミティブで表現できる最大の数であるNumber.MAX_SAFE_INTEGER
よりも大きな数値を扱えるプリミティブです。ECMAScript 2020で採り入れられました(「JavaScriptの次の仕様ES2020で追加されることが決定した新機能まとめ」参照)。
通常の数値型のままでは、Number.MAX_SAFE_INTEGER
を超えた数値の演算に誤差が生じてしまいます。
const maxInt = Number.MAX_SAFE_INTEGER; const maxIntPuls2 = maxInt + 2; console.log(maxIntPuls2 - maxInt); // 1 <- 誤差が生じる
bigint
型の数値をつくるのが、BigInt()
関数です。数値のあとにn
を添えて、リテラルで書くこともできます。
const maxIntBig = BigInt(Number.MAX_SAFE_INTEGER); const maxIntPlus2Big = maxIntBig + 2n; console.log(maxIntPlus2Big - maxIntBig); // 2n
bigint
型について詳しくは、リファレンスの「BigInt」をお読みください。
symbol型
ECMAScript 2015で備わったSymbol
のプリミティブは、グローバルに一意の値です。Symbol()
関数でつくり、引数には説明のための文字列が渡せます。ただし、引数の文字列から値がつくられるわけではありません。戻り値は、つねに一意のsymbol
型プリミティブです。
const name = Symbol("name"); console.log(name === Symbol("name")); // false
symbol
型について詳しくは、リファレンスの「Symbols」をご覧ください。
作成者: 野中文雄
作成日: 2021年06月03日
Copyright © 2001-2020 Fumio Nonaka. All rights reserved.