定数に対してFlowの型を設定する場合、工夫というか、トリッキーな書き方をしないと上手く動かない。
業務で必要になり調べ、GitHubのIssueで解決策を見つけたのだが、日本語の資料や記事は見当たらなかった。
ちょっとした小ネタだが、誰かの役に立つかもしれないし、自分の備忘録も兼ねて書いておく。
Flowのバージョンは0.46.0
で、動作確認をしている。
まず、何も考えず普通に書いてみる。
const NORMAL_MEMBER_CODE = 'qwerty';
const ADMIN_CODE = 'admin';
type Code = NORMAL_MEMBER_CODE | ADMIN_CODE;
function sendCode(code: Code): void {
console.log(code);
}
sendCode('admin');
最初に、NORMAL_MEMBER_CODE
とADMIN_CODE
という2つの定数を定義している。
sendCode
の引数は必ずCode
という型であり、これは、NORMAL_MEMBER_CODE
かADMIN_CODE
のいずれかである。
何もおかしなところはない。
しかしこれをFlowでチェックすると、エラーになる。
6: type Code = NORMAL_MEMBER_CODE | ADMIN_CODE;
^^^^^^^^^^^^^^^^^^ string. Ineligible value used in/as type annotation (did you forget 'typeof'?)
6: type Code = NORMAL_MEMBER_CODE | ADMIN_CODE;
^^^^^^^^^^^^^^^^^^ NORMAL_MEMBER_CODE
6: type Code = NORMAL_MEMBER_CODE | ADMIN_CODE;
^^^^^^^^^^ string. Ineligible value used in/as type annotation (did you forget 'typeof'?)
6: type Code = NORMAL_MEMBER_CODE | ADMIN_CODE;
^^^^^^^^^^ ADMIN_CODE
(did you forget 'typeof'?)
と出ているので、Code
の定義を以下のように書き換えてみる。
type Code = typeof NORMAL_MEMBER_CODE | typeof ADMIN_CODE;
これなら確かに、エラーは出ないようになる。
しかしこれは、Code
はstring
ですと定義しているだけであり、文字列なら何でも通ってしまう。
例えばsendCode('hoge');
でも、Flowはエラーを出さない。
qwerty
とadmin
以外ではエラーを出すのが、意図する挙動である。
正解は、以下。
const NORMAL_MEMBER_CODE: 'qwerty' = 'qwerty';
const ADMIN_CODE: 'admin' = 'admin';
type Code = typeof NORMAL_MEMBER_CODE | typeof ADMIN_CODE;
function sendCode(code: Code): void {
console.log(code);
}
sendCode('admin');
これで、正しく動くようになり、qwerty
とadmin
以外ではエラーを出すようになった。
参考資料