【備忘録】三項演算子がESLint Rule no-unused-expressionsでエラーとなる
Angular製のアプリを作成しているときに、三項演算子がESLint Ruleのno-unused-expressionでエラーになりました。その原因と対処方法を備忘録として残します。なお、この現象に対して、Angular製というのは関係がないため、記事では簡単なTypeScriptのソースコードで説明します。
発生した現象
ESLintのrulesで、no-unused-expressions
が有効になっているとき、
module.exports = { "env": { "browser": true, "es2021": true }, "extends": [ "eslint:recommended", "plugin:@typescript-eslint/recommended" ], "parser": "@typescript-eslint/parser", "parserOptions": { "ecmaVersion": 12, "sourceType": "module" }, "plugins": [ "@typescript-eslint" ], "rules": { "no-unused-expressions": ["error"] } };
こんな感じで、条件分岐の短縮として三項演算子を使用すると、
const temperature = 25; temperature >= 25 ? console.log('暑いですね') : console.log('普通ですね');
error Expected an assignment or function call and instead saw an expression
とエラーになります。
$ npx eslint test.ts 3:1 error Expected an assignment or function call and instead saw an expression no-unused-expressions ✖ 1 problem (1 error, 0 warnings)
そもそもno-unused-expressionsとは
An unused expression which has no effect on the state of the program indicates a logic error. For example, n + 1; is not a syntax error, but it might be a typing mistake where a programmer meant an assignment statement n += 1; instead. Sometimes, such unused expressions may be eliminated by some build tools in production environment, which possibly breaks application logic.
すごく簡単に説明すると、n + 1
や0;
というどこにも代入していないようなコードはコンパイルエラーにはならないけど、不具合などの原因になる可能性があるから禁止しますね。というルールになります。
なぜ三項演算子でエラーになるのか
結論から言うと、三項演算子はif文とは違い、変数に代入ができる式(Expression)であり、no-unused-expressions
は使用されていない(変数への代入が行われていない)式をエラーとするからです。
jsprimer.net
上記の記事では、文(Statement)とは、末尾に;
がつき、変数に代入ができないもの、式(Expression)とは変数に代入できるものとあります。
つまり、文(Statement)であるif文は変数に代入することができず、式(Expression)である三項演算子は変数に代入することができます。
const test1 = if(temperature >= 25){ return '暑いですね。' } else { return ' 寒いですね。'} // エラー const test2 = temperature >= 25 ? '暑いですね' : '普通ですね'; // エラーではない
そして、no-unused-expressions
は使用されていない式、つまりどこにも代入されていない式をエラーとして判定するため、結果を変数に格納していない三項演算子はエラーと判定されてしまいます。
対処法
三項演算子の結果を変数に格納し使用する
三項演算子の結果を変数に格納したり、別のメソッドの引数にすることでエラーを回避できます。
const temperature = 25; console.log(temperature >= 25 ? '暑いですね' : '普通ですね');
三項演算子ではなく、if-else文を使用する
三項演算子を使用せずにif-else文を使用することで、エラーを回避できます。
const temperature = 25; if (temperature >= 25) { console.log('暑いですね'); } else { console.log('普通ですね'); }
no-unused-expressionsのオプション allowTernaryをtrueにする
no-unused-expressionsには結果の代入を行わない三項演算子を許可するオプションallowTernary
が存在します。
allowTernary
をtrue
にすることで三項演算子を許可します。
"rules": { "no-unused-expressions": ["error", { "allowTernary": true }] }
おわりに
no-unused-expressions
のルールが存在すると考えると、三項演算子をif文の短縮形として使用するのがそもそも間違いなのかもしれません。このエラーについて調べるにあたり、文(Statement)と式(Expression)の違いについても知ることになり、とても勉強になりました。