at backyard

Color my life with the chaos of trouble.

日付の比較計算で The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.というエラーが出たときの対処方法

The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.というエラーが出たときの対処方法

趣味で作っていた下記のプログラムで実際に遭遇したエラー。

github.com

下記のような日付をソートするための処理を書いていた。

data.entries.sort(function (a: Entry, b: Entry) {
  // @ts-ignore
  return new Date(a.publishedAt) - new Date(b.publishedAt);
});

@ts-ignoreを使っているが、ここでTypeScript コンパイラがエラーを吐いていて、仕方なく @ts-ignore をつけて対応を後回しにしていた。

Dateオブジェクトの比較とvalueOfメソッド

この日付計算のプログラムだが、JavaScriptとしては問題なく動くと思うがTypeScriptのCompileは通らない。
ちゃんと調べたわけではないので間違っているかもしれないが、普段このような計算を行う際は暗黙的に数値同士で比較するように処理は動く。
つまり裏側では date1.valueOf() - date2.valueOf() というような計算処理が動いているのではないかと思う。

ちなみにvalueOfはDateオブジェクトのプリミティブ値を返してくれるメソッドだ。

developer.mozilla.org

だが、TypeScriptはそのような暗黙的な処理の書き方は見逃してくれないようだ。 よって、下記のようにvalueOf を用いて、明示的に数値同士の計算を行うように修正をすることでコンパイルエラーは消えた。

data.entries.sort(function (a: Entry, b: Entry) {
  return new Date(a.publishedAt).valueOf() -
    new Date(b.publishedAt).valueOf();
});

TypeScriptを使っていると、普段JavaScriptでいかに暗黙的な処理を自身が無意識に書いているかを気づかせてくれるので、そういう意味でも勉強になると思った次第。

以上備忘録でした。