Posted at

TypeScriptの型宣言の柔軟さに漏らしそうになる


TypeScriptによるWindowフレームワーク開発

 現在TypeScriptで、JavaScriptから簡単に使えるWindowフレームワークを作成している。その開発中に感じた、TypeScriptで漏らしそうになった機能を紹介したい。


 複雑な条件の引数があっさりと記述できる

 Windowsの標準コントロールのようなListViewクラスを作成したときの話だ。ヘッダを追加するにあたり、ラベルとサイズを指定するaddHeaderというメソッドを作成した。引数は以下のように設定できるようにした。

 ・単純にテキストを書けば、ヘッダが一つだけ追加される

 ・配列で渡せば複数ヘッダが追加される。

 ・引数の最後にヘッダ一つあたりの幅が指定できる

 ・配列の中に配列を作ると個別の幅を指定することが出来き、指定方法は[ラベル,幅]となる。

 実際にコードで書くと以下のように使える

let listView = new JSW.ListView

listView.addHeader('あいうえお') //リストビューにヘッダを一つ追加
listView.addHeader('あいうえお',150) //幅を指定してヘッダを一つ追加
listView.addHeader(['あいうえお','かきくけこ'],200) //ヘッダを追加し、それぞれの幅を200に設定
listView.addHeader([['あいうえお',50],'かきくけこ','さしすせそ'],200) //'あいうえお'を幅50、'かきくけこ'と'さしすせそ'を幅200に

 普通に考えれば、恐ろしく複雑な条件である。しかしこれをTypeScriptで宣言すると、あっさりと出来てしまうのだ。

addHeader(labels: string | (string | [string, number])[], size?: number)

 以上となる。

 これできちんと型チェックが動作するのだ。TypeScriptを実際に使う前は、JavaScriptに静的型付けがちょっと追加された程度の言語だと認識していたが大間違いである。


 キャストいらず、型推論がすごい

 さらにすごいのが型推論能力だ。

function Test(value:string|{a:number,b:string}){

if(value instanceof String){
console.log(value.a) //文法チェックの時点でエラー
}else if(value instanceof Object){
console.log(value.a) //こちらは文法エラーにならない
}
}

 instanceofの結果に基づいてvalueの型を確定させている。つまり文法チェックの時点でif文の結果すら型推論に含まれているのだ。これならキャストは必要ない。静的型付けが半動的型付けになって自由度が高い上に、きっちり文法チェックが働く。これでは糞尿垂れ流しでも文句は言えないだろう。


 文字列によるパラメータの型

 クラスにオーバーロードの定義を加えておく

addEventListener(type: 'itemClick', callback: (event: LISTVIEW_EVENT_ITEM_CLICK) => void): void

addEventListener(type: 'itemDblClick', callback: (event: LISTVIEW_EVENT_ITEM_CLICK) => void): void
addEventListener(type: 'itemDragStart', callback: (event: LISTVIEW_EVENT_DRAG_START) => void): void
addEventListener(type: string, callback: any, options?) {
super.addEventListener(type, callback, options)
}

以下のように文字列でイベントを指定すると、引数が確定する

let listView = new JSW.ListView

listView.addEventListener('itemClick',event=>{
//eventの型が確定しているので入力補間が効く
})


まとめ

 Qiitaのタグ・ランキングには常に圏外のTypeScriptではあるが、実はとんでもない実力を秘めている言語である。まだまだ成長過程であり、今後どれだけ便利になっていくのか、まったく底が見えない。