概要
https://www.typescriptlang.org/tsconfig#strictNullChecks
{
"strictNullChecks": true
}
Nullable な値に対してプロパティの呼び出しを行う記述をエラーにします。
詳細
type Obj = {
hoge?: string;
};
const obj: Obj = {};
const trimmed = obj.hoge.trim();
trim
はString.prototype.trimです。
この Obj 型のプロパティhoge
は?
付きなのでundefined
が入ります。
hoge
がundefined
の場合、trim
を呼ぶとランタイムエラーになります。
このオプションがtrue
の場合は、以下のようにコンパイル時にエラーになり、そのままでは通りません。
index.ts:25:17 - error TS2532: Object is possibly 'undefined'.
25 const trimmed = obj.hoge.trim();
これを回避するためには、値がundefined
ではないことを保証すれば OK です。例えば、
const obj: Obj = {};
if (obj.hoge != undefined) {
const trimmed = obj.hoge.trim();
}
など。
?
(Optional Chaining
)
ES2019 から、JS にも Optional Chaining が登場しました。
Optional chaining (?.) - JavaScript | MDN
Ruby で言うぼっち演算子です。
つまり、Nullable な値に対してもプロパティ呼び出しが可能になります。
先ほどの例で言うと
const obj: Obj = {};
const trimmed = obj.hoge?.trim(); // hoge? となっている
これでコンパイルが通ります。
ただし、hoge
がundefined
だった場合はtrimmed
はundefined
になるので、その後の取り回しには注意が必要です。
Optional Chaining のおかげで JS コードからかなり煩雑なコードを消すことができるようになりましたね。
!
(Non-Null Assertion Operator
)
ちなみに、こちらは JS の仕様ではなく TS の仕様ですが、!
(Non-Null Assertion Operator
)でもエラーを消すことができます。
が、実質ランタイムエラーになるだけなので、基本的にやってはいけません。
唯一許容できるとすれば、コードの論理上、非undefined
であることが定まっているが、tsc
の型推論が効かない場合のみです。
例えば下記のようなコード。
const component = props.func && <div onClick={() => props.func!()}>contents</div>;
この場合、props.func &&
を通っている時点でprops.func
が非undefined
であることは確定していますが、JSX の中で渡そうとすると型推論が効かず、!
をつけないとコンパイル時にエラーになります。
とはいえ、気づかないうちに&&
の左辺の条件が変わってprops.func
が Non-Null であることを保障できなくなっていても気づけないので、型チェック的な観点で言うとこれもベストではありません。
見ると不安になるので、!
を使わなくて良いようなコードにすることを心がけたいですね。