flowtype v0.32.0 changes

flowtype v0.32.0がリリースされました

Release v0.32.0 · facebook/flow · GitHub

この変更では待望のgen-flow-filesコマンドが追加されています。 これはflowtypeのシンタックスで書いたjsファイルから、型定義情報を生成するコマンドです。

これまではライブラリ作者が型定義情報を提供しようとした時に、外部提供用の.js.flowを別途用意する必要がありましたが、これによってその必要がなくなります。 まだalpha-levelなので、安心して使うにはもう少し待つ必要がありそうですが、これは非常に捗りますね。

その他何点か機能追加があったので試してみます。

gen-flow-files コマンドの追加

先ほども書きましたが、待望の機能です。 flowtypeのシンタックスで書いたjsファイルから、型定義情報を生成することができます。

  • calcRectArea.js
// @flow

type Rect = { x: number, y: number };
export default function calcArea(rect: Rect) {
  return rect.x * rect.y;
}

このjsファイルに対して、flow gen-flow-files [filename] を実行します。

$ flow gen-flow-files calcRectArea.js
// @flow

declare export default function(rect: {x: number, y: number}): number;

declare export default function(rect: {x: number, y: number}): number; という型定義情報が出力がされてますね。

便利。

exact object types シンタックスの追加

これまでflowにおいて、オブジェクトの型定義は{ hoge: type}のみでしたが、より正確なオブジェクトを定義するためのシンタックスとして{| hoge: type |}が追加されました。

{ hoge: string}と記述した場合には、「少なくともstring型であるhogeプロパティが含まれること」という検証がされます。 {hoge: 'hoge', bar: 'bar'}というオブジェクトは、この型定義に当てはめた時にbarが余計に含まれていますが、上記の条件は満たしているため検証が通ります。

{| hoge: string |}と記述した場合には、「string型であるhogeプロパティのみを持つこと」という検証がされます。 {hoge: 'hoge', bar: 'bar'}というオブジェクトは、barプロパティを余計に持ってしまっているためエラーとなります。

従来の型定義

// @flow

type Rect = { x: number, y: number };
function calcArea(rect: Rect) {
  return rect.x * rect.y;
}

console.log(calcArea({ x: 2, y: 3, z: 4 }));
$ flow
No errors!

exact object types

// @flow

type Rect = {| x: number, y: number |};
function calcArea(rect: Rect) {
  return rect.x * rect.y;
}

console.log(calcArea({ x: 2, y: 3, z: 4 }));
$ flow
exact.js:8
  8: console.log(calcArea({ x: 2, y: 3, z: 4 }));
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function call
  8: console.log(calcArea({ x: 2, y: 3, z: 4 }));
                          ^^^^^^^^^^^^^^^^^^^^ property `z`. Property not found in
  3: type Rect = {| x: number, y: number |};
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^ object type


Found 1 error

resource filesのデフォルト型定義情報の追加

.css, .jpg, .png, .gif, .eot, .svg, .ttf, .woff, .woff2, .mp4, .webm のファイルをrequireしたときにデフォルトで型定義情報が付与されるようになりました。 .cssはObjectとなり、他のリソースファイルはstringとなります。

(this list is not configurable at the moment).

だそうなので、そのうち設定ができるようになりそうです。

自分で型定義を与えたい場合には、これまでどおりmodule.name_mapperで設定する必要があります。

参考: Flow | Advanced Configuration

flowはtype-at-posコマンドで、指定した位置の変数の型定義を出力することができるので、これを使って試してみます。

  • requireResource.js
// @flow

import css from './test.css';
import gif from './test.gif';

console.log(css);
console.log(gif);
$ flow type-at-pos requireResource.js 6 13
Object
/Users/joe-re/src/try-flow-032/requireResource.js:6:13,6:15

See the following locations:
/Users/joe-re/src/try-flow-032/requireResource.js:6:13-15:
Flow assumes requiring a .css file returns an Object

6 13という引数は6行目の13列という指定です。css変数を指定しています。 想定どおりオブジェクトが返ってます。

[~/src/try-flow-032]$ flow type-at-pos requireResource.js 7 13
string
/Users/joe-re/src/try-flow-032/requireResource.js:7:13,7:15

See the following locations:
/Users/joe-re/src/try-flow-032/requireResource.js:7:13-15:
string

こちらはgif変数を指定しています。 こちらも想定どおりstringが返ってます。