JavaScriptのプログラムを書く時はTypeScriptを使っています。
元々はJavaScriptを直接書いていたのですが、使いたかったReactのコンポーネントがTypeScriptで書かかれていたため、試しにTypeScriptで書いてみたのがきっかけでした。
結局そのコンポーネントは使わなかったのですが、TypeScriptが便利で、それ以来TypeScriptで書くようになりました。
TypeScriptとは?
TypeScriptとは、Microsoftが開発している言語で、JavaScriptにコンパイルされて使われる言語です。
JavaScript界隈では、AltJSという、それ単独では動かないが、それからJavaScriptに変換して利用される言語というものがあり、TypeScriptもAltJSの1つです。
どちらかと言うと言語というより、C言語のプリプロセッサみたいなもので、JavaScriptを使いやすくする言語拡張のようなイメージでしょうか。
TypeScriptにしてここが良かった
名前チェック機能
まずタイプミスが無くなって、実行時のエラーが激減しました。
例えば下記のような変数名・関数名のタイプミスがあったとします。
function test(){ console.log("TEST_01"); } function run_01(){ let str = "TEST_02"; console.log( strrrr ); // strrrrがタイプミス } function run_02(){ testttt(); // testttt()がタイプミス } run_01(); // ここでエラーが表示されて終了 run_02(); // ここでエラーが表示されて終了
実行すると、タイプミスの箇所でエラーになり、実行はそこで終了するのですが、エラーになるのは実際にタイプミスの箇所を実行しようとした時です。
逆に言えば、タイプミスの箇所が呼ばれない限りプログラムはエラーにはならず動作し続けるので、一見正常に動作しているように見えます。
そして、プログラムが稼働してずっと後になってから、タイプミスの箇所が呼ばれた時に初めてエラーになり、そこでやっとタイプミスに気づきます。
一方TypeScriptは、名前に「Type」とついているように、JavaScriptに型・名前宣言を強要します。なので上記のタイプミスは、TypeScriptからJavaScriptへのコンパイルでエラーになるのですぐに分かります。
これのおかげでエラーが激減して、作業効率がずいぶん上がりました。
ダウングレード機能
次に、JavaScriptのバージョンを気にしなくてよくなり、最新のJavaScriptの言語仕様でプログラムが書けるようになりました。
ブラウザとそのバージョンによって、対応しているJavaScriptのバージョンが異なります。
ブラウザに対応できるよう意識しながらJavaScriptを書くのは大変なので、JavaScriptの開発界隈では、コードは最新のJavaScriptの言語仕様で書き、それをコンパイルしてダウングレードしたものを使ういとうことをよくやります。
そういったJavaScriptのダウングレードは「Bable」などを用いて行うのですが、TypeScriptも同様のダウングレード機能をそなえているので、TypeScriptを使えば、他の設定なしで最新のJavaScriptのバージョンでプログラムを書くことができます。
導入方法
- npmを使っているのでしたら
npm install -g typescript
でインストールされます。- バージョンを固定したい場合は
npm install --save-dev typescript
でpackage.json毎に決めることもできます
- バージョンを固定したい場合は
- ファイル拡張子は「.ts」で、実行コマンドは「tsc」です。
tsc test.ts
と打つとコンパイルされ「test.js」が生成されます。
- TypeScriptを設定ファイルで設定することができます。設定ファイル名は「tsconfig.json」で「tsc」コマンドを実行するフォルダ配下に置きます。
- tsconfig.jsonは無くても構いません
困った時の対処方法
設定
TypeScriptの設定は結構面倒で、正しいプログラムを書いているつもりでも、コンパイルエラーになることも多いかと思います。
tsconfig.jsonは「tsc」コマンドのオプションを設定ファイル化したものなので、オプションのドキュメントを参考にtsconfig.jsonを修正していきます。
外部モジュール
TypeScriptは型定義が必要なのですが、npmでインストールする外部モジュールはJavaScriptで記載されているので、コンパイル時に、そのモジュールのTypeScriptの定義が無いとエラーになることがあります。
そんな時は「@types/モジュール名」で定義がnpmで配信されている場合があるので、npm install --save-dev @types/モジュール名
を試してみます。
「@types/モジュール名」を探してみたが無かった場合は、プログラム内で、モジュールを読み込んだ変数を「any」型にして定義が無くてもエラーにならないようにします。(例:const m:any = require(~);
)
React
慣れるまでは「create-react-app」でcreate-react-app my-app --scripts-version=react-scripts-ts
とすると、React雛形のTypeScriptバージョンが作成されるので、それをベースに修正していくのがトラブルが少ないかと思います。
参考 - https://github.com/Microsoft/TypeScript-React-Starter
ちなみにTypeScriptでも中にJSXは書け、その場合の拡張子は「.tsx」となります。
困った時の「any」
型関連でエラーが発生する場合は
const test:any = 123;
等、宣言時の型をanyにする。console.log((test as any));
等、使用箇所で型をanyにする。
にすると、とりあえずエラーは収まります。
個人的な利用方針
TypeScriptはJavaScriptを、必要な箇所だけ部分的に拡張した言語に過ぎないので、JavaScriptをそのままTypeScriptにしても動きます。(TypeScriptのコンパイル設定を緩めにする必要はありますが)
TypeScriptには、列挙型・インターフェース・Genericsなど、JavaScriptには無い言語仕様が色々追加されているのですが、あまりTypeScript固有の機能は使わず、素に近いJavaScriptになるようにしています。
TypsScriptは型定義が売りなので怒られそうですが、型定義・宣言もほとんど使わず、「any」型にしています。
では何のためにTypeScriptを使っているかというと、前述のタイプミスチェックのためで、このためだけにTypeScriptを使っているといってもオーバーではないくらい恩恵を受けています。
その他
JavaScriptを使っているが、最近TypeScriptが気になりかけている。という方でしたら、使ってみることをオススメします。
JavaScriptをそのままTypeScriptのコンパイラにかけて、タイプミスだけ検知するような使い方なら、ほとんど覚えることはないですし、それでもTypeScriptを使う価値は十分に得られるんじゃないかなぁと思います。
おまけ
TypeScriptはJavaScriptのように、書いて即実行ができず、ある程度お膳立てが必要です。
毎回準備するのは手間なので、下記のような雛形を作っておいてフォルダコピーして使っています。
TypeScriptソースは「src」フォルダに置くようにし、npm run test
で「build」フォルダにJavaScriptが生成され実行します。
構造
- フォルダ
- src
- test.ts
- package.json
- tsconfig.json
- src
test.ts
console.log('test');
package.json
{ "scripts": { "build": "tsc", "start": "node ./build/test.js", "test": "npm run build && npm run start" }, "devDependencies": { "@types/node": "", "typescript": "" } }
tsconfig.json
{ "compilerOptions": { "module": "commonjs", "target": "es6", "noImplicitAny": true, "allowUnreachableCode": true, "moduleResolution": "node", "sourceMap": true, "outDir": "build", "baseUrl": ".", "paths": { "*": [ "node_modules/*", "src/types/*" ] } }, "include": [ "src/**/*" ] }