facebook/flow 実践編

  • 48
    Like
  • 0
    Comment
More than 1 year has passed since last update.

先に書いた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にしておく。