たとえば、このようなコードがあるとする。
interface TestType {
foo: number;
}
function test(data: TestType | null) {
if (data === null) return 0;
return data.foo;
}
デバッグやテストなどのため、test
が呼ばれたらとりあえず throw
したいとする。
interface TestType {
foo: number;
}
function test(data: TestType | null) {
throw "test"; // 追加
if (data === null) return 0;
return data.foo;
}
すると、以下のようなエラーが出てしまった。
Unreachable code detected.
'data' is possibly 'null'.
無条件で throw
しているためその後のコードが実行されない、というのはわかる。
しかし、data === null
のチェックをしているからその下の data.foo
の data
は null
にはならないはずなのに、これが null
になりうるという間違った主張をされてしまっている。
迷惑である。
そこで、これを回避する方法を考えた。
試した結果、throw
を条件が必ず真になる if
文の中に入れることで、Unreachable code 判定を回避しつつ、無条件で throw
を実行できそうであることがわかった。
interface TestType {
foo: number;
}
function test(data: TestType | null) {
if (1) throw "test"; // 追加
if (data === null) return 0;
return data.foo;
}
これでエラーが出なくなった。
data.foo
の data
が null
になりうるという間違った主張もしてこなくなった。
if (true) throw "test";
では、エラーが出てしまった。
今回は、TS Playground の v5.6.2 で検証を行った。
もしも、将来のバージョンで条件 1
では恒真だとバレてしまい、エラーが出てしまった場合は、
if (!false) throw "test";
if (1 < 2) throw "test";
if (Math.sin(1) < 2) throw "test";
など、もう少し複雑な条件を試してみるといいかもしれない。(将来のバージョンなので、これらで本当にうまくいくかはわからないが)