背景
仕事でいきなり経験ほぼゼロのJavaScript界隈に飛び込んで開発を進めています。
コードレビューにおいて型がないのが苦痛との指摘を受け、静的な型チェックを導入しました(してもらいました)。
ただ、何もかもが始めてのことなので学習がてら、flowtypeの書き方についてまとめてみました。
周辺環境は以下の通りです。
Babel + webpack + flowtype + react
ES2015準拠で書いていきましょうという体でやっています。
導入
yarn add -D flow-bin
で追加
大まかな手順
- チェックするjsファイルを1つ選ぶ
- そのjsファイルをチェック対象にする
- 型チェックを実施する
- エラーを修正する
- flowtypeのためのコードを抜き出して本番用コードとする
3と4を繰り返し、ひとまずエラーがすべて解消できることを目指す。
手順2.チェック対象にする方法
おまじない的に、対象ファイルの先頭行に// @flow
を記述することでチェック対象となる。
現在のチェック対象ファイル一覧は、flow ls
で確認できる
デフォルトのままだと、使用する関連ライブラリなどもチェック対象となってしまう。
これによって不慮のエラーが発生することがあるようなので、チェック不要なファイルについては.flowconfig
のignoreに追加する
手順3.型チェックの実施
flow自体をインストールしている場合は flow
で実行できる
yarnでflowを追加している場合は、yarn run flow
として実行する(上記のflow ls
なども同様)
手順4.エラーを修正する
書き方に倣って、エラーの発生した箇所を修正する
型について
利用できる型
- 独自型(後述)
- string
- number
- boolean
- any (何か。これを使うとflowを使う旨味がない!って怒られるのだろうか)
- null (nullしか指定できないって何)
- empty (何を指定しても通らなさそうな感じの)
- void (戻り値に指定する)
独自型の定義
規定の型以外でも独自に定義して利用することができる。
今回は、JSONのスキーマを作成する用途で独自型の定義をしていた。
type MyType = {
name: string;
price: number;
}
Advancedな感じの型
調べていく中で見つけたが今回は使用していない
// stringでもnumberでも
function foo(value: $Either<string, number>) {
console.log(value);
}
foo(333); // OK!
foo('333'); // OK!
これとnullやらvoidをあわせると素敵で複雑な挙動になりそう
flowtypeの書き方
変数の定義
型定義を追加するにはコロン(:)で繋いで型を記述する
const hoge: string = '735'; // OK!
const hoge: string = 735; // NG!
関数の定義
変数の定義同様に記述する
function foo(name: string) {
console.log('hello, ' + name);
}
戻り値の定義
カッコの後ろにコロン(:)で繋いで型を記述する
function foo(name: string): number {
return name.length;
}
foo('350'); // OK!
foo(350); // NG!
クラスのフィールドの定義
クラスの先頭で定義したもののみ使うことができる
下のコードのように、定義していないもの(home)を使おうとするとエラーが出る
class Foo {
name: string;
constructor(name: string) {
this.name = name; // OK!
this.home = name; // NG!
}
}
const foo = new Foo('FOOOOO');
配列の定義
配列の定義をするには、Array<型>とする
function foo(numbers: Array<number>) {
}
Arrayのようにすると空の配列を渡すことが出来るっぽい。
が、結局中身がemptyだから要素を追加することはできない...。
Predicateの定義
Lodashを使用する中で、filterに渡すためのpredicateを定義する機会があった。
これについてはanyを指定することでSkipした。
(ちゃんとしたやり方があるかどうかはそのうち調べたい)
参考
flow による型のある世界入門 - SlideShare
0からはじめるFlow Part.1 - console.lealog();
redux アプリに flow を導入したところまでのメモ - わからん
flowtypeのUtility Typeについて その1 - Qiita
https://github.com/facebook/flow/blob/master/src/typing/type.ml
静的型チェッカーflowのクラスでPrivateなフィールドを定義するメモ - Namiking.net
Lambda(Node.js)にFlowによる静的型チェックを導入してみる | Developers.IO