LoginSignup
133

More than 3 years have passed since last update.

Facebook Flowの初見の感想

Last updated at Posted at 2014-11-19

mizchi君の記事を見て、だいぶ感想が違ったので書くことにした。
なお、僕はTypeScript信者であることを踏まえてこの記事を読んでほしい。

あと、最初はまじめに記事にしようと思ったけどダルくなってきたのでメモをそのまま投げる。

TypeScriptより良い型推論

Flowパイセンの一番偉いところはTypeScriptより型推論が強いところだと思った。#

/* @flow */
function foo(x) {
  return x * 10;
}
foo('Hello, world!');
$> flow
hello.js:5:5,19: string
This type is incompatible with
  hello.js:3:10,15: number

関数foo内部のxは、* 演算子を利用しているのでnumberであると推論している。
これが実際の利用箇所でstringを引数にしているので怒ってくれるわけだ。偉いな!
Flow is a static type checkerと謳っているとおり、完全にpure JavaScriptで書かれているプロジェクトに対して、新しいlintの一種であるかのように導入できるのは大きなアドバンテージだろう。

なお、もちろん型注釈を明示的に与えることもできる模様。

/* @flow */
function foo(x) {
  return x.reduce((p, c) => p + c.charAt(0), 0);
}

foo([false, true]);
$ flow check

/private/tmp/flow/hello.js:3:33,43: call of method charAt
Property not found in
  /private/var/folders/c8/yszwff5d4z57z0d4sn04yy140000gn/T/flow_vvakame/flowlib_7e8f1b7/lib/core.js:54:1,56:1: Boolean

Found 1 error

スゲェ。でもエラーメッセージわかりにくい。

nullを許容しない

ここより抜粋。

/* @flow */

function length(x) {
  return x.length;
}

var total = length('Hello') + length(null);
03_Null/nulls.js:4:10,17: property length
Property cannot be accessed on possibly null value
  03_Null/nulls.js:7:38,41: null

nullを想定していない関数に対して、nullを渡すと怒られる。
強い。

以下のようなnullチェックがある関数だと怒られないらしい。
強い。

/* @flow */

function length(x) {
  if (x !== null) {
    return x.length;
  } else {
    return 0;
  }
}

var total = length('Hello') + length(null);

TypeScript 1.4で導入予定のtype guardsに近い発想だ。
しかし、大きなbreaking changeになるのでTypeScriptには少なくともしばらくは入らんだろうなぁ。羨ましい。

型定義

普通にTypeScriptのlib.d.tsを参考にしてるっぽい
コンパイルエラーで表示されたメッセージから以下を拾うことができた。

This type is incompatible with
/**
 * Copyright (c) 2014, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the "flow" directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 */
/* JS primitives
   cf. http://typescript.codeplex.com/sourcecontrol/latest#typings/lib.d.ts
*/

配列

Array<number>形式しか受け付けないのかなと思って以下を試したけど普通にチェック通った。

/* @flow */
function foo(x: number[]) {
  return x.reduce((p, c) => c + p, 0);
}

union types

ふつーにある

弱くチェックするモード

/* @flow weak */

型定義ファイルの使い方

コマンドラインオプションで頑張る
多分 .flowconfig に書いてもイケる。

コンパイルの仕方

react-toolsで型注釈機械的に取り除くだけ?
default valueにも対応してるようだけどうまく動かなくね?ブラウザ側が対応すれば使えるみたいなTypeScript以上のストロングスタイルなのかまさか。

そもそも型定義ファイルいるの?

なくてもパワーでわっしょいできそう

Flowの処理系使ったら既存JSから雑な型定義ファイル生成できそうじゃね?

オナシャス!

TypeScriptとの互換性

今んとこ割りとありそうに見える。
mixedの導入 とか、微妙にTypeScriptにないものがあるような気もする。
Flow is superset of TypeScript 感。

tupleがサポートされている

TypeScriptと同じ感じっぽいけどTypeScriptより頭悪い

/* @flow */
var tup = ["1", 1, 2, "positive"];
tup.unshift(1);
console.log(tup[1] * tup[2]); // unshiftしたので 1st * 2nd は number * string だ!

これがエラーチェックをすり抜ける。
TypeScriptの場合、明示的にtupleと型注釈を与えない限りtupleにならないので、(string | number)[] となる。

nullable の導入

ここより

/* @flow */
var o: ?string = null;
print(o.length);

良さそう…?な気もする?

intersection types

ここ

うーん、これunion typesで表現可能な範囲だし、言語設計者が単に入れたかったら入れた感あるな…。

dynamic type tests

ここ
TypeScriptがtype guardsと呼んでいるものをdynamic type testsと呼んでいるっぽい気がする。

生JSに型注釈版のサジェストをくれる

/* @flow */
function foo(x) {
  return x.reduce((p, c) => p + c.charAt(0), "");
}

foo(["JavaScript", "TypeScript"]);
$ flow suggest hello.js
/private/tmp/flow/hello.js
--- old
+++ new
@@ -1,6 +1,6 @@
 /* @flow */
-function foo(x) {
-  return x.reduce((p, c) => p + c.charAt(0), "");
+function foo(x: Array<string>) : string{
+  return x.reduce((p: string, c: string) => : stringp + c.charAt(0), "");
 }

 foo(["JavaScript", "TypeScript"]);

…強い!!
神機能じゃね?arrow function expressionあたりがちょっとバグってるけど。

第二のインストール方法

$ brew install opam
$ opam init
$ eval `opam config env`
$ opam install flowtype
$ which flow
/Users/vvakame/.opam/system/bin/flow

総評

アンダース・ヘルスバーグ御大の設計は繊細で強いなと思った。
御大だったら入れてないだろコレ…みたいな感想をなんかテキトーに2〜3回くらい思った気がする。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
133