個人的に、TypeScriptでVueコンポーネントを(なるべく型安全に)書くためのライブラリを作っている。
という話を この辺 に書いた。
「型安全」というのはつまり「正しくないコードを書いたらコンパイルエラーになる」ということなので、「与えられたコードをコンパイルしたら期待通りのコンパイルエラーが発生する」というテストが必要になる。
で、そういうテストを書いてたんだけど、他所でも同じようなことをしたいケースが出てきたのでそこのところをライブラリ化した。
ソースは こちら
使い方
-
テスト用の
tsconfig.json
を作成する。コンパイル結果を出力する必要はないので、noEmit
を指定しておくといいと思う。test/tsconrfig.json{ "compilerOptions": { "target": "es6", "module": "commonjs", "noEmit": true, "strictNullChecks": true }, "filesGlob": [ "*.ts" ], "exclude": [ "node_modules" ] }
-
テスト用のソースファイルを作成する。
test/common.tsexport interface Payload { foo: string; bar: number; } export function dispatch<K extends keyof Payload>(name: K, payload: Payload[K]): void { // Do something }
これは普通にコンパイルが通るはずのコード。
test/should-succeed.tsimport { dispatch } from "./common"; dispatch("foo", "value"); dispatch("bar", 1);
コンパイルエラーを期待するコードの場合、エラーがおきるはずの行に
////
に続けてエラーコードを記述する。:
に続けて、期待するエラーメッセージの一部(または正規表現)を書くこともできるtest/should-fail-1.tsimport { dispatch } from "./common"; dispatch("foo", 1); //// TS2345 dispatch("fooo", "value"); //// TS2345: type '"fooo"' is not assignable dispatch("foo", 3); //// TS2345: /'3' is not assignable .* 'string'/
これはFailするサンプル
test/should-fail-2-wrong.tsimport { dispatch } from "./common"; dispatch("foo", 1); dispatch("foo", 2); //// TS2345: type '1' is not assignable
-
tsc-test
コマンドを実行する$ tsc-test -p test/tsconfig.json
で、こんな感じに結果が出力される
制限事項とか
1行に複数のコンパイルエラーが発生するケースに対応できない
想定されるエラーをインラインで書くので、1行に2つ以上エラーが出てくるとだめ。
これはまあ別にいいかなと思っている。
node_modules/@types
を自動で読んでくれない¥
tsc
でコンパイルする場合は node_modules/@types
の下にある d.ts
を自動で読みにいってくれるのだけど、LanguageService APIでコンパイルする場合はそこまではやってくれないっぽくて、どうすればいいか調査中。
知っている方がいたら教えてください。
とりあえずは、tsconfig.json
で明示的に lib
を指定するとか、lib.d.ts
に書いておくとかすれば回避できるはず。
/// <reference types="node" />
TODO
- 上の
@types
の問題をなんとかする -
--watch
の対応とインクリメンタルビルドとかやりたい