FlowのType Refinementsが便利だった。使ってるFlowのバージョンは0.44.2。
Union Typeに対してifやswitchを使って、変数の型を検証することで、そのブロック内で検証済みの型として利用することができる。
具体的にはこんな感じ。
// @flow
function logString(value: string) {
console.log(value);
}
function logBoolean(value: boolean) {
console.log(value);
}
function test(value: string|boolean) {
if (typeof value === 'string') {
logString(value);
} else if(typeof value === 'boolean'){
logBoolean(value);
// logString(value); だとflowがエラーを吐く
}
}
これがどういう時に嬉しかったかというと、最近flux/utilsを使う機会があって、Actionの型定義とReduceStoreでのActionの処理が素直かつ型安全にかけた(と思ってる)。
具体的にはこんな感じ。Stateは今回関係ないのでanyとしておく、ActionとStoreは実際には別ファイルに書いてる。
// @flow
type Action = {
type: 'STRING_ACTION',
value: string,
} | {
type: 'BOOLEAN_ACTION',
value: boolean,
}
function reduce(state: any, action: Action) {
switch (action.type) {
case 'STRING_ACTION':
logString(action.value);
break;
case 'BOOLEAN_ACTION':
logBoolean(action.value);
// logString(action.value);だとエラー
break;
}
}
実際のflux/utilsを使ったコードは、fluxのexampleだと、flux-flowかflux-asyncあたりで該当のコードを確認できる。
https://github.com/facebook/flux/blob/master/examples/flux-flow/src/AppActions.js
https://github.com/facebook/flux/blob/master/examples/flux-flow/src/AppStore.js
リファクタリングとかも楽になるし、レールに乗れてるうちはFlowは便利だなというのが今のところの印象。