5
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

いきなりJavaScript : flowtypeをゼロから始めて1ファイル完成するまで

Last updated at Posted at 2017-05-09

背景


仕事でいきなり経験ほぼゼロのJavaScript界隈に飛び込んで開発を進めています。

​コードレビューにおいて型がないのが苦痛との指摘を受け、静的な型チェックを導入しました(してもらいました)。

ただ、何もかもが始めてのことなので学習がてら、flowtypeの書き方についてまとめてみました。

周辺環境は以下の通りです。
Babel + webpack + flowtype + react

ES2015準拠で書いていきましょうという体でやっています。

導入

yarn add -D flow-bin で追加

大まかな手順

  1. チェックするjsファイルを1つ選ぶ
  2. そのjsファイルをチェック対象にする
  3. 型チェックを実施する
  4. エラーを修正する
  5. 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をあわせると素敵で複雑な挙動になりそう :innocent:

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

5
7
0

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
5
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?