初心者が学ぶflowtype入門 Ver.1.0

# 前回のあらすじ

[Node.js入門 Ver.0.2](https://qiita.com/ikkitang/items/5ee36fe5786893be5eee)

[Node.js入門 Ver.0.5](https://qiita.com/ikkitang/items/a5b7fe752dd70eb15fc5)

以前、TypeScriptを扱うにあたって、node.jsを一度勉強してみる事にした。今回はそれのブログを書いた時に flowtype もやってみては？っていうFBを頂いたのでありがたいFBはすぐやる。

# flowtype

# そもそも flowtype とは

ざっといろんなサイトをあさってみたけど flowtypeってのは TypeScriptと同じようにJavaScriptに静的型付を提供するプログラミング言語って事らしい。

では、TypeScriptとの違いはなにか？ってところに行き着く。

既存のTypeScriptでは辛いところ等があるんじゃないのか、ってところで調べてみると、「TypeScriptは新規プロジェクトに導入するのは簡単だけど既存プロジェクトの場合はなかなか難しい。 」っていうのがあるらしい。

なんだろう？ hogehoge.ts を書きなおすから？ 

「flowtypeであれば既存のプロジェクトにも型の恩恵を付加する事ができる」
ここがflowtypeとTypescriptの違いとなってくる、ってのがまず flowtype を導入する時の基準になるんかなーって理解した。

# flowtype書いてみる。

## まず開発環境構築

```terminal
# node 環境を作成
$ npm init -y
# flowtypeをinstall
$ npm install --save flowtype flow-bin
```

## flowtypeの初期化

次に flowtypeのコマンドを設定する。 これにより `npm run-script flow 〜` で flowのコマンドを実行する事ができるようになる。

```diff:package.json
{
  "name": "flowtype-sample",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
+    "flow": "flow"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "flow-bin": "^0.74.0",
    "flowtype": "^2.0.0"
  }
}

```

この後、 `rpm run-script flow init ` を実行します。  `.flowconfig` が定義されました。

## 無視リストの作成

flowtype は `rpm run-script flow check` コマンドを実行する事により、型チェックを行ってくれますが、この時何も指定しない場合は プロジェクトの全ファイルを検査します。

**node_modules** を含めてしまうと失敗してしまう事も多いため、まずは自分のコードだけを対象とするため、無視リストに node_modules 以下のファイルを無視にする設定を記述します。

```diff:.flowconfig 
[ignore]
+ .*/node_modules/.*

[include]

[libs]

[lints]

[options]

[strict]

```

こういった柔軟に無視リストを定義できるところが既存のものに入れやすいと評価されている部分なのだと思います。

# flowtypeでのコーディング

以下、コードは下記のサンプルと同じ内容で勧めていきます。

[TypeScript入門 Ver.1.0](https://qiita.com/ikkitang/items/9acaf6a166f771e5ce6f)

[TypeScript入門 Ver.2.0](https://qiita.com/ikkitang/items/22f205bd5d2cd7644605)

## flowtype で HelloWorld

どうやら、flowtypeでは .ts ではなくて、 **`.js` に記述していく**方式で進むようです。

また、 `// @flow` と記述する事でFlowチェッカーの対象になる、とのことでした。

```js/app.js
// @flow
console.log("Hello! Node.js × flowtype");
```

## flowtype の型チェッカーを実行。

```terminal
# ルートディレクトリ上で実行.
$ npm run-script flow check

> flowtype-sample@1.0.0 flow /Users/hogehoge/flowtype-sample
> flow "check"

Found 0 errors
```

おお、これで `Found 0 errors` となり、型チェックに通った事が確認されました。

## flowtypeでチェックの通ったファイルを実行

```terminal
$ node src/app.js
Hello! Node.js × flowtype
```

きた！！ やったぞ！ マスターした。

（これ・・・チェックしただけじゃん。。。) 

## ちゃんと型チェックしてる？

```typescript:src/app.js
// @flow

let message = 'flowType';
message = 2;
console.log("Hello! " + message);
```

`npm run-script flow check` 。。。 `found 0 error` 。。。あれ(´・ω・｀)？？

## 型アノテーションが付けられるらしい。

```js:src/app.js
// @flow

let message: string = 'flowType';
message = 2;
console.log("Hello! " + message);
```

`npm run-script flow check` 

```terminal
~~

Error ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ src/app.js:4:11

Cannot assign 2 to message because number [1] is incompatible with string [2].

     1│ // @flow
     2│
 [2] 3│ let message: string = 'flowType';
 [1] 4│ message = 2;
     5│ console.log("Hello! " + message);


〜〜
```


おお！ちゃんと弾いてる。 `Cannot assign 2 to message because number [1] is incompatible with string [2].` 
 ちゃんと型チェックしてくれてていい！


## if文とかどうなの？

`if (評価式)` 良くも悪くも、 評価式に なんでも入れる事ができるのは JavaScriptの良さだったりするんだけど、どうだろう？ Swiftとかだと 比較はBool型とかしか入れられない。

```typescript:src/app.js
// @flow
let value : number = 0;
if (value) {
    console.log("定義済み!");
} else {
    console.log("未定義");
}
```

`npm run-script flow check` 。。。 `found 0 error` 想定どおり。

## 違う型は比較できる？

```typescript:src/app.js
// @flow
let value : number = 1;
let str : string = "1";

if (value == str) {
    console.log("同じ");
} else {
    console.log("違う");
}
```

さて、チェックしてみる。 お、失敗するねー。

```terminal
$ npm run-script flow check

Error ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ src/app.js:5:5

Cannot compare number [1] to string [2].

 [1] 2│ let value : number = 1;
 [2] 3│ let str : string = "1";
     4│
     5│ if (value == str) {
     6│     console.log("同じ");
     7│ } else {
     8│     console.log("違う");

```

型違いだからNGだよ、と。

## httpモジュールをインポートしてHTTPサーバーを立てる。

```javascript:src/app.js
// @flow
const http = require('http');
const server = http.createServer();
let message = 'flowtype';

server.on('request', function(request, response) {
    response.writeHead(200, {'Content-Type': 'text/plain'});
    requestHandler(request, response);
});

function requestHandler(request, response) {
    response.end('Hello World & ' + message + ' for HTTP');
}
```

こちらでチェックをかけてみる。 `found 0 errors` だね。

`node src/app.js` をおこなって、httpサーバーを立てる事で 今回の例だと 5001ポートで サーバーが　listen（待機） 状態になる。

`http://localhost:5001/` にアクセスする事で、想定どおり、`Hello World & flowtype for HTTP`とレスポンスを得る事ができた。

# まとめ

取り敢えず、ざっと書いてみた。

flowtypeは既存のコードにちょっとずつ入れる、ってのを目指してあるためか、 既存のJSファイルに `// @flow` を書いてチェックを入れながら・・・みたいな事ができるな、って感じた。

推論をどこまでしてくれるんだろう？ってのは気になるところだね。

```typescript:src/app.js
// @flow

let message = 'flowType';
message = 2;
console.log("Hello! " + message);
```

これのチェックがエラーにならなかったのはなんでだろー？

後、個人的にエラーメッセージは typescriptの方がわかりやすかった気がした。 

# 宣伝

転職をきっかけにいろいろな試みをやってます。

## ほぼ日AWS

[ほぼ日AWS](https://ikkitang1211.hatenablog.jp/archive/category/%E3%81%BB%E3%81%BC%E6%97%A5AWS)

AWSの各ソリューションについて 「このソリューションはどういうもの？」 って観点でまとめてみたものです。

## もくもく独書 for Swift実践入門

[もくもく独書 for Swift実践入門](https://ikkitang1211.hatenablog.jp/archive/category/Swift%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80)

Swift実践入門の書籍を毎日読みながら必要に応じてコードを書いてまとめていっているものです。