突然ですが問題です
文字列の変数を宣言するとき、型注釈にString
とstring
のどちらを使いますか?
let foo: String;
let bar: string;
あまり意識したことない方もいるのではないでしょうか?
答え
string
の方を使いましょう。
その理由について見ていきましょう。
プリミティブ型とラッパーオブジェクト
string
はプリミティブ型で、String
はラッパーオブジェクトです。
プリミティブ型について
文字列、数値、論理値などの基本的な値の型のことです。
プリミティブ型はimmutableという特性を持ちます。つまり、変更することができません。
また、プリミティブ型はメソッドやプロパティを持ちません。
ラッパーオブジェクトについて
ラッパーオブジェクトは、プリミティブ型の値をラップしたオブジェクトのことです。
平たく言うと、プリミティブ型を便利に使えるようにしたものです。
便利に使えるようにしたものですので、ラッパーオブジェクトはlength
などのプロパティやtoUpperCase()
などのメソッドを持っています。
typeof
で確認してみると
プリミティブ型とラッパーオブジェクトについて、typeof
演算子で確認してみると以下のようになります。
const foo = new String("foo");
const bar = "bar";
console.log(typeof(foo)); // -> object
console.log(typeof(bar)); // -> string
プリミティブ型でもlength
を使える?
プリミティブ型はプロパティなどを持たないという話がありましたが、実際、プリミティブ型でlength
を使うことができます。
const bar: string = "bar";
console.log(bar.length) // -> 3
ラッパーオブジェクトであるString
のプロパティであることがわかります。
プリミティブ型のプロパティにアクセスするとき、暗黙的にラッパーオブジェクトに変換される仕様となっています。
したがって、プリミティブ型であっても、ラッパーオブジェクトと同じようにメソッドなどを使うことができます。
結論
String
ではなくstring
を使いましょう。
ラッパーオブジェクトではなくプリミティブ型を使いましょう。
TypeScriptのドキュメントにも
The type names String, Number, and Boolean (starting with capital letters) are legal, but refer to some special built-in types that will very rarely appear in your code. Always use string, number, or boolean for types.
と書かれています。
ラッパーオブジェクトを使うと
-
typeof
演算子を使うとobject
となり、型がわからない(Stringのラッパーオブジェクトを使ってもstring
であることがわからない) - 演算子が使えない