前回のあらすじ
以前、TypeScriptを扱うにあたって、node.jsを一度勉強してみる事にした。今回はそれのブログを書いた時に flowtype もやってみては?っていうFBを頂いたのでありがたいFBはすぐやる。
flowtype
そもそも flowtype とは
ざっといろんなサイトをあさってみたけど flowtypeってのは TypeScriptと同じようにJavaScriptに静的型付を提供するプログラミング言語って事らしい。
では、TypeScriptとの違いはなにか?ってところに行き着く。
既存のTypeScriptでは辛いところ等があるんじゃないのか、ってところで調べてみると、「TypeScriptは新規プロジェクトに導入するのは簡単だけど既存プロジェクトの場合はなかなか難しい。 」っていうのがあるらしい。
なんだろう? hogehoge.ts を書きなおすから?
「flowtypeであれば既存のプロジェクトにも型の恩恵を付加する事ができる」
ここがflowtypeとTypescriptの違いとなってくる、ってのがまず flowtype を導入する時の基準になるんかなーって理解した。
flowtype書いてみる。
まず開発環境構築
# node 環境を作成
$ npm init -y
# flowtypeをinstall
$ npm install --save flowtype flow-bin
flowtypeの初期化
次に flowtypeのコマンドを設定する。 これにより npm run-script flow 〜
で flowのコマンドを実行する事ができるようになる。
{
"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 以下のファイルを無視にする設定を記述します。
[ignore]
+ .*/node_modules/.*
[include]
[libs]
[lints]
[options]
[strict]
こういった柔軟に無視リストを定義できるところが既存のものに入れやすいと評価されている部分なのだと思います。
flowtypeでのコーディング
以下、コードは下記のサンプルと同じ内容で勧めていきます。
flowtype で HelloWorld
どうやら、flowtypeでは .ts ではなくて、 .js
に記述していく方式で進むようです。
また、 // @flow
と記述する事でFlowチェッカーの対象になる、とのことでした。
// @flow
console.log("Hello! Node.js × flowtype");
flowtype の型チェッカーを実行。
# ルートディレクトリ上で実行.
$ npm run-script flow check
> flowtype-sample@1.0.0 flow /Users/hogehoge/flowtype-sample
> flow "check"
Found 0 errors
おお、これで Found 0 errors
となり、型チェックに通った事が確認されました。
flowtypeでチェックの通ったファイルを実行
$ node src/app.js
Hello! Node.js × flowtype
きた!! やったぞ! マスターした。
(これ・・・チェックしただけじゃん。。。)
ちゃんと型チェックしてる?
// @flow
let message = 'flowType';
message = 2;
console.log("Hello! " + message);
npm run-script flow check
。。。 found 0 error
。。。あれ(´・ω・`)??
型アノテーションが付けられるらしい。
// @flow
let message: string = 'flowType';
message = 2;
console.log("Hello! " + message);
npm run-script flow check
~~
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型とかしか入れられない。
// @flow
let value : number = 0;
if (value) {
console.log("定義済み!");
} else {
console.log("未定義");
}
npm run-script flow check
。。。 found 0 error
想定どおり。
違う型は比較できる?
// @flow
let value : number = 1;
let str : string = "1";
if (value == str) {
console.log("同じ");
} else {
console.log("違う");
}
さて、チェックしてみる。 お、失敗するねー。
$ 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サーバーを立てる。
// @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
を書いてチェックを入れながら・・・みたいな事ができるな、って感じた。
推論をどこまでしてくれるんだろう?ってのは気になるところだね。
// @flow
let message = 'flowType';
message = 2;
console.log("Hello! " + message);
これのチェックがエラーにならなかったのはなんでだろー?
後、個人的にエラーメッセージは typescriptの方がわかりやすかった気がした。
宣伝
転職をきっかけにいろいろな試みをやってます。
ほぼ日AWS
AWSの各ソリューションについて 「このソリューションはどういうもの?」 って観点でまとめてみたものです。
もくもく独書 for Swift実践入門
Swift実践入門の書籍を毎日読みながら必要に応じてコードを書いてまとめていっているものです。