先に書いたfacebook/flowファーストインプレッション - Qiitaでは自分でコード書いたりしなかったんだけど、今回はちゃんと手触り込みで。
Hello World!
mkdir flow-playground
cd flow-playground
flow init
vim hello.flow.js
/* @flow */
function foo(x) {
return x * 10;
}
foo('Hello, world!')
flow check
型エラー起こしてみる
~/s/flow-playground $ flow check
/Users/mizchi/sandbox/flow-playground/hello.js:4:11,22: number
This type is incompatible with
/Users/mizchi/sandbox/flow-playground/hello.js:3:37,42: string
Found 1 error
たぶんここじゃ伝わらないけど、出力がめっちゃカラフル
Classes
/* @flow */
class A {
a: number;
constructor(public prop: number){
}
}
new A(3);
TypeScriptにあるコンストラクタ初期化はない。
/Users/mizchi/sandbox/flow-playground/classes.js:5:15,20: Use of future reserved word in strict mode
というわけでこれは通る
/* @flow */
class A {
a: number;
constructor(prop: number){
this.a = prop;
}
}
new A(3);
Union and Type Alises
/* @flow */
class A {
a: number;
constructor(prop: number){
this.a = prop;
}
}
class B {
b: number;
constructor(prop: number){
this.b = prop;
}
}
type T = A | B | string;
var x: T = new A(3);
まあ動く。
lambda function
試してたら次のエラーが出た
/* @flow */
var _: any = require('lodash');
var arr: number[] = _.map([1,2,3], (n: number) => n * n);
console.log(_.map([1,2,3], (n) => n * n));
/Users/mizchi/sandbox/flow-playground/requiring.js:4:39,39: Unexpected token :
(n: number) => {}
この構文はまだサポートしてないのかな?
require
sub.js
/* @flow */
module.exports = function(n: number): number{
return n * n;
}
main.js
/* @flow */
var sub = require('./sub');
sub('hoge');
~/s/flow-playground $ flow check
/Users/mizchi/sandbox/flow-playground/main.js:4:5,10: string
This type is incompatible with
/Users/mizchi/sandbox/flow-playground/sub.js:3:30,35: number
ちゃんとrequire先の型をみてくれてる!
コンパイル
react-toolsつかえとのこと
npm install -g react-tools
どうでもいいんだけど react-toolsでjsxコマンド入るのなんでや
~/s/flow-playground $ jsx --strip-types --harmony classes.js
built Module("classes")
/* @flow */
function A(prop) {"use strict";
this.a = prop;
}
function B(prop) {"use strict";
this.b = prop;
}
var x = new A(3);
たしかに!!!!!
hoge.flow.jsをnode環境でrequireできるようにする
nodeでrequireするとき、拡張子がhoge.flow.jsだったら上の変形を書けて読み込むようにする。
でっち上げるためにさっくりcoffeeで書いた。
fs = require 'fs'
reactTools = require('react-tools')
require.extensions['.flow.js'] = (module, filename) ->
code = fs.readFileSync(filename).toString()
transformed = reactTools.transform(code, {harmony: true, stripTypes: true})
module._compile(transformed)
require './hello.flow.js'
これでflow checkしつつnode環境で動かすことが出来そう。
あとで読み込み部分はnpm packageにしておく。