JavaScriptで次のような関数があったとします。
function increment(num) {return num + 1;}console.log(increment(1));
ただの引数をインクリメントして返すだけのその名もincrement
です。
上記を実行します。 実行時のファイル名をincrement.js
としていますが、異なる名前にした方は読みかえてください。
$ node increment.js2
予想とおりのなんでもない関数ですが、この関数が次のように呼ばれたらどうでしょうか。
function increment(num) {return num + 1;}console.log(increment('1'));
呼び出し時の引数1
が'1'
になりました。これだけでこの関数の結果は大きく変わってしまいます。
$ node increment.js11
これは算術演算子の+
(加算)を期待してこの関数を作ったと思われるところに文字列が入ってしまったため+
が文字列連結として解釈されてしまったことが原因です。
もしこれが金額の計算だったとしたら大変なことになります。
TypeScriptを使うと、コーディングの時点でこのような型の不一致による意図しない挙動を抑えられるようになります。
ファイル名の変更は拡張子を.js
から.ts
に変更するだけです。
$ mv increment.js increment.ts
これをエディターで開くとincrement()
の引数にあたるnum
のところで何か言われます。
Parameter 'num' implicitly has an 'any' type, ...
これはTypeScriptはこの引数に対していかなる型も与えられていないよ(いわゆるany
)ということを言っています。そこで型を付加します。付加する型はnumber
型です。
function increment(num: number) {return num + 1;}console.log(increment('1'));
すると今度は呼び出し側でTypeScriptコンパイラからメッセージが表示されます。
Argument of type '"1"' is not assignable to parameter of type 'number'.`
このメッセージの意味は「この引数の'1'
はnumber
型ではないよ」という至極まっとうな指摘です。
ひとまずこの警告を完全無視してトランスパイルをしてみます。
$ tsc increment.ts
するとやはり警告が出てしまいます。
Argument of type '"1"' is not assignable to parameter of type 'number'.console.log(increment('1'));~~~Found 1 error.
このように事前にコードに潜んでいる危険を、コーディングまたはトランスパイルの時点で検知できます。
今回は引数のみの紹介となりましたが、戻り値にも型を指定することができます。これによりその関数内で意図しない結果を返さないかどうかの検知に使うことができます。
戻り値も書いたincrement.ts
の完全版は次のようになります。
function increment(num: number): number {return num + 1;}
もちろん、この関数で戻り値をstring
型などnumber
型ではない型に設定するとTypeScriptから指摘を受けます。
Type 'number' is not assignable to type 'string'.return num + 1;~~~~~~~~~~~~~~~