souki-paranoiastのブログ

地方都市でプログラマーをやっている人のブログ。技術ネタ以外も少し書く。メインの言語はJava。https://paranoiastudio-japan.jimdo.com/ に所属

【TypeScript】JSの暗黙の型変換に頼っていた文字列の数値変換はどう書くのか

前置き

例によってJSからTSに書き換える作業中の出来事を抽出。 javascript - 0とかjavascript minus zeroとかjavascript 明示的 型変換とか幾つか調べたけど直接的な答えはヒットしなかった。JavaScript畑の人たちには当たり前の事実なんだろうか。教えてほしい。

概要

JavaSciptで文字列を数値に変換する方法は幾つか存在するが、比較的よく使われるイディオムに下記のものがある。

const a = "1" - 0;
console.log(a, typeof a); // 1, "number"

これを、TypeScriptではどう記述するのか?という問題。

const a = "1" - 0; // Compile error!!

つまり、正確に言えばTypeScript関係ない。でもJavaScriptを書くときに、結構意識しない気がするんだよねコレ。暗黙の変換を使用して問題になることの方が少ないだろうし。
少なくとも詳細な動きまでは私は意識したことない。そもそも個人的にnullとかundefinedや数値変換できないような文字列とかに対してやりたくないんだよね。無駄に確認項目増えそうで。

回答

殆どのケースではNumber()が同じ動きになる。
殆どのケースというか、多分これで正しいのだけど、正確な答えは正直わからなかった。。。英語ムズカシイ

const obj = {
    valueOf: function() {
        return 123;
    }
}
console.log(obj.valueOf()); // 123
console.log(obj - 0); // 123 // 文字列 -> 数値変換の場合はvalueOf()の戻り値が使われる。文末の参考リンクを参照
console.log(Number(obj)); // 123
console.log(parseFloat(obj)); // 123
obj++; // ちなみにincrementもできる
console.log(obj); // 124

メモ

「文字列 - 数値」を計算する際に、文字列は数値へ暗黙の型変換が行われる。 そのロジックはECMAScriptの仕様書のここあたりに記載されている。 Number()へのリンクとかが貼られていれば確証が持てるのだけど、パース手順みたいなのが書いてあるんだよねBNF的な。 時間あるときにちゃんと読むかな。正直そんな時間あるならこんなこと意識しなくて済むような記述にすれば良いと思う。折角TypeScriptなんだし。回避できる言語仕様は回避した方が脳のリソースを無駄にしなくて良いし!というと言い訳になるか。

補足

  • new Number()Number()は違う。前者はラッパーオブジェクトを作成するし、後者はプリミティブオブジェクトを生成する。MDNの例が詳しい。

  • parseFloat()ではダメ。parseFloat(null)null - 0Number(null)の結果でわかる。

参考

追記(2020-03-06)

なんて思ってたら、「+」のイディオムは使えるようですよ(´・ω・`) bigintでは使えないようですが、十分な気はする。

let aaa = "123";
console.log(typeof aaa);  // string
console.log(typeof +aaa); // number

aaa = null;
console.log(typeof aaa); // object
console.log(typeof +aaa); // number
console.log(+aaa); // 0
console.log(Number(aaa)); // 0


aaa = 123n;
console.log(typeof aaa);
// console.log(typeof +aaa); // Uncaught TypeError: Cannot convert a BigInt value to a number
// console.log(+aaa); // Uncaught TypeError: Cannot convert a BigInt value to a number
console.log(Number(aaa));

参考URL:

https://qiita.com/uhyo/items/cc92a553059274d85403#%E5%8D%98%E9%A0%85%E6%BC%94%E7%AE%97%E5%AD%90