[TypeScript]幻の型を実行時に召喚、メソッドの引数や戻り値を自動的にチェックする


[TypeScript]幻の型を実行時に召喚、メソッドの引数や戻り値を自動的にチェックする

 前回の内容とほとんど同じですが、それをnpmに登録したので記事を焼き直します。

TypeScriptと型

 TypeScriptの型は、入力補完やコンパイル段階までのエラーチェックには利用できるものの、実行結果に影響を与えることは出来ません。理由は簡単、コンパイルされた段階で、型に関する情報が影も形も無くなるからです。無いものは使えません。

 しかしtsconfig.jsonの設定項目には実験的オプションとして、以下の二つの項目があります。

  • experimentalDecorators
    クラスやメソッド、パラメータに追加機能を割り込ませる機能
    クラスを継承せずに動作をカスタマイズすることが出来る
  • emitDecoratorMetadata
    コンパイル結果に型情報を埋め込む機能
    ただし埋め込まれる型情報は貧弱なので、それほど期待してはいけない

 上に記した通り、取得可能な情報はそれほど多くありません。

拾える情報

 今回はクラスメソッドの型チェックを行うモジュールの紹介ですが、以下の型をチェックできます。

  • number
  • string
  • boolean
  • Array
  • Function

 これだけです。複合的なものやオブジェクトは判定できません。

利用手順

事前に以下のパッケージをインストールしてください

npm i ts-method-checker

まずはクラスを作成し、チェック機能を入れたいメソッドに@CHECKを挿入します。

import {CHECK} from 'ts-method-checker';

class Test {
  @CHECK //this will check arguments and return types at runtime
  func01(a: number, b: string, c: boolean): number {
    console.log(a, b, c);
    return 0;
  }
  @CHECK
  func02(a: number, b: string, c: boolean): number {
    console.log(a, b, c);
    return "A" as never; //Set the return value to string type
  }
}

定義したクラスを使ってみます
コンパイル時の型チェックをすり抜けるように、クラスのインスタンスを格納する変数はanyにします
しかし実行時の型チェックが効いているので、間違った型の入出力を行うと例外が発生します

// Create instance
const test:any = new Test();

//do it right
test.func01(0, "A", true);  //OK

//Incorrect number of arguments
try {
  test.func01(true); //exception "Invalid number of arguments"
} catch (e) {
  console.error(e);
}

//Incorrect argument type
try {
  test.func01(0, 10, true); //exception "Invalid argument type"
} catch (e) {
  console.error(e);
}

//Call the method with the wrong return value
try {
  test.func02(0, "A", true); //exception "Invalid return type"
} catch (e) {
  console.error(e);
}

まとめ

 今回の内容を使うと、判定できないもの以外は一応チェックするようになるので、TypeScriptのプログラムがほんの少しではありますが安全になります。やることもメソッドの前に@CHECKだけなので、簡単に利用することが出来ます。