前々から出すよ出すよ詐欺してたflowがやっと出た。大雑把にはfacebook製のTypeScriptだと思っていれば良いです。
まだnpmで提供されてなくて、 Flow | Getting started with Flow
で実行バイナリが配られてる。
npmで提供されてない理由は、たぶんocamlで書かれてるから。Future Planにjs_of_ocamlでコンパイルされたものが提供されると書いてあった。
DLして適当なパス通った場所に置いてつかう。
cp ~/Downloads/flow/flow ~/bin
TypeScriptとの比較
思想はTypeScriptと同じなので、大枠は一緒だといってよい。
ぱっと見気になったのは、Nullableの書式が違うのとかあるけど、もっと大きな違いもたくさんある。
FlowとTypeScriptにあるもの
- declareキーワードによるアノテーション
- ES6 classes
- Generics
ここらへんは共通
Flowにあるもの
- 高速なオンラインコンパイラ
- Union Type
- type aliases
- React JSX連携
- jsdocコメントが読める
とくに一番大きな差はunion types
/* @flow */
var x: number | string = 0;
とはいえこれはtypescript1.4でも入る予定だった気がする。
Type Alias
/* @flow */
type T = number;
var x: T = 0;
こういうやつ。
たぶん組み合わせて
type T = number | string
とかけると思うしGADTSっぽい何かができるのでは。
Flowにないもの
- ES6 module
- npm package
つまり現時点でTypeScriptとFlowは互換ではない。とくにES6 moduleの差は大きいようにみえる。typescriptのコードはmodule使わずに書かれていないものはほぼないので。
名前空間解決
TypeScript は ///<reference path='' />
で参照するコードを指定していたけどFlowの名前空間は commonjs requireで require('path/to/file') した先の型を読んでる模様。browserify/node.jsフレンドリー。node派には嬉しい。
Future Plan
気になったもの抜粋
- TypeScriptのd.tsの変換ツール
- js_of_ocamlでコンパイルしたjsの提供(npm install flowとかするため)
- エディタ連携
- ErrorTraceを賢く
- ES6 module
雑感
TypeScriptはは常にまるごとコンパイルするが、ファイル単体が変更されたときに依存性を解析してそのファイルをコンパイルする。これが大きな違い。
TypeScriptは名前空間がグローバルベースでcommonjs requireベースで解決する運用が苦手だった印象があるが(-m commonjs時とその他の互換がなかったりとか)、Flowはそこが強い印象。
基本的にTypeScriptとの互換はないものと考えたほうが良い。将来的にFeatureがそろって(とくにmodule)相互運用するにしても、相当な縛りがないと動かないはず。
自分は最近Atom Shell環境で生きてるんでflow使おうかなって気になってる。