TypeScript をなんとなく使っていたものの、ちゃんとやり直したいので取り組んでみる。
目次
参考
TypeScript って何だろうね
TypeScript の README より抜粋です。
TypeScript is a language for application-scale JavaScript. TypeScript adds optional types to JavaScript that support tools for large-scale JavaScript applications for any browser, for any host, on any OS. TypeScript compiles to readable, standards-based JavaScrip
TypeScript は、アプリケーション規模ための JavaScript です。
「ちょこっとページに動きをつけるくらいならいいけど、アプリケーションみたいな規模だとつらいでしょ?だから型を提供するよ。」
ってことだそうな。
(翻訳を使いつつの解釈。)
環境設定
適当なディレクトリで以下を入力する。
1 | npm install --save-dev typescript ts-node |
(以降の説明で都度tsc
でビルドしているところもts-node
で実行すれば、直接実行まで確認できます。)
tsconfig.json を作成します。
内容は、オライリーを参考にしながらES2015
をES2020
に変更しています。
1 | { |
./dist
と./src
の二つのディレクトリを作成しておく。
最初の一歩
src/index.ts に以下を書いてみます。
1 | console.log("Hello world"); |
こちらを用意して、npx tsc index.ts
を実行すると、index.js
が作成されます。
1 | console.log("Hello world"); |
こちらをnode dist/index.js
で実行すると、見たままHello world
と表示されます。
コンパイルしても、同じなのは TypeScript が、JavaScript の記法自体は受け入れるから。
なので、index.ts を TypeScript らしく書き換えてみます。
以下のように、出力する文字列にstring
という型をつけて宣言するようにしました。
1 | const msg: string = "Hello world"; |
改めてnpx tsc index.ts
を実行すると、以下のindex.js
が作成されます。
1 | var msg = "Hello world"; |
型に関する記述がなくなりました。
こちらをnode dist/index.js
で実行すると、見たままHello world
と表示されます。
ちなみに、最初のconsole.log("Hello world");
だけ書いたindex.ts
をnode src/index.ts
としても実行できます。
型定義を記述した index.ts では、node src/index.ts
と実行しても以下のエラーになりました。
1 | const msg: string = "Hello world"; |
少し探る
違う型のものを与えてしまったら
前述 index.ts を以下のように変更します。
1 | const msg: number = "Hello world"; // <= stringをnumberに変更しました |
改めてnpx tsc index.ts
を実行すると、以下のエラーが発生します。
1 | index.ts:1:7 - error TS2322: Type 'string' is not assignable to type 'number'. |
変数 msg は、number 型だから string 型のものを入れてくれるな。というわけですね。
このチェックがあれば、文字列に数字を入れてしまったり、といったミスは確かに防ぎやすくなりますね。
型アノテーション と 暗黙的な型推論
前述の index.ts で記述したconst msg: string = "Hello world";
の: string
の部分のことを、明示的な型アノテーションと言うそう。アノテーション = 注釈
という意味で、確かに変数が文字列であると注釈しています。
以下のように型アノテーションを書かなかった場合の index.ts を用意します。
1 | let msg = "Hello world"; // <=msgに文字列を代入 |
こちらを用意して、npx tsc index.ts
を実行すると、以下のエラーが発生します。
1 | index.ts:2:1 - error TS2322: Type 'number' is not assignable to type 'string'. |
変数 msg は、string 型なので number 型を入れてれるなってことですね。
アノテーションを書いていないけど、ソースコードから型の不整合を見てくれるのが、暗黙的な型推論。だそうです。
生の JavaScript だと、文字列で数字を入れているのか?、数値として設定しているのか?なんてことがあるので、ミスが防止できそうです。
型の指定って結構自由?
オライリーには、サンプルコードに以下のものがあります。
1 | let d: boolean = true; |
いわゆる型としてイメージできるもの以外も型に設定できるということです。
ここで気が付いて、以下のものを書いてみました。
1 | const n1: number = 1; |
数字を型アノテーションに使用すると、その数字以外の入力でエラーになることを確認できました。
ということは、文字列でもできるはずです。
1 | const s1: string = "text"; |
型に特定の文字列を指定できました。特定の文字列だけを受け取る変数の宣言をするようなとき生かせそうです。
こういった特定の値を型にしているるものをリテラル型と呼ぶそうです。
オブジェクト型の修飾子
型の定義には便利なオプションの設定がある。
1 | const obj: { a?: number; readonly b: string } = { b: "readonly" }; |
?
をつけたものはオプション、設定をしなくてもよくなる。readonly
をつけたものは、読んでの通り読み取り専用になる。
型に名前をつける
type
とinterface
で型に名前をつけることができる。
1 | // 二つのstring型の変数を含む型Name |
列挙型
TypeScript には列挙型がある。
JavaScript にないのに?と思いはしたもののどうなっているのか確認します。
以下のindex.ts
を用意します。
1 | enum Key { |
こちらをコンパイルした index.js は次の記述になっていました。
1 | var Key; |
また、const をつけることでより厳密な、制限をすることができます。
1 | enum Key1 { |
エラーになる箇所を除外して改めて、コンパイルしてみると次のようになっていました。(多少の改行あり)
1 | var Key1; |
この動作だけ見ると、const enum しか使わない気がしました。
アンビエント宣言
例として、参照元jQuery の$
に型を与える例があるんですが、他に試す例が出せないのでまた後で確認したいところです。
(チャレンジとしては jQuery 以外で。)
TypeScript を本格的に勉強し始めましたが、とりとめもなくメモだけの記事です。
正直有益な情報って現段階では提供 0 とは感じていますが、しばらく続く見込みです。
ではでは。