新しいことにはウェルカム

技術 | 電子工作 | ガジェット | ゲーム のメモ書き

TypeScriptのススメ

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のバージョンでプログラムを書くことができます。

導入方法

  1. npmを使っているのでしたらnpm install -g typescriptでインストールされます。
    • バージョンを固定したい場合はnpm install --save-dev typescriptでpackage.json毎に決めることもできます
  2. ファイル拡張子は「.ts」で、実行コマンドは「tsc」です。
    • tsc test.tsと打つとコンパイルされ「test.js」が生成されます。
  3. 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

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/**/*"
    ]
}

関連カテゴリー記事

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com

www.kwbtblog.com