状態のunion
画面には状態がある
ゆめさくのポートフォリオ一覧は、サーバーから作品データを取ってきて表示します。取ってくるあいだ画面は空っぽで、取り終わったら一覧が出て、失敗したらエラーが出ます。この 3 つの状況を、通信状態と呼びます。
JavaScript ではよく、真偽値を並べて表していました。
let isLoading = true;
let hasError = false;この持ち方には穴があります。isLoading と hasError が両方 true になれる、という穴です。読み込み中でありながら失敗もしている、という状況はありえないのに、コードの上では書けてしまいます。
3 つの状態を 1 つの型にする
リテラル型の union にすると、ありえない組み合わせを最初から作れなくします。
type FetchStatus = "loading" | "success" | "error";
let status: FetchStatus = "loading";変数は 1 つなので、同時に 2 つの状態にはなれません。取りうる状態がちょうど 3 つだと、型を見ただけで分かります。
この FetchStatus は、このあと第5章のつくる回でも使いますし、React 実践コースでも同じ形で出てきます。名前と 3 つの値をこのまま覚えてください。
未定義の状態はエラーになる
let status: FetchStatus = "loaded";
// エラー Type '"loaded"' is not assignable to type 'FetchStatus'."loaded" は "loading" に似ていますが、型に無いので止まります。文字列で状態を持つと必ず出てくる打ち間違いを、型が引き受けてくれます。
状態で分岐する
状態は、比較して使います。
type FetchStatus = "loading" | "success" | "error";
function isBusy(status: FetchStatus): boolean {
return status === "loading";
}比べる相手も型に含まれているかどうかが検査されます。
if (status === "loded") {
}
// エラー This comparison appears to be unintentional because the types
// 'FetchStatus' and '"loded"' have no overlap.条件の書き間違いは、いつまでも false になるだけで気づけない種類のバグです。それを型が拾ってくれるのは大きな利点です。
手を動かす
演習では FetchStatus を自分で定義して、作品一覧を表示してよい状態かどうかを判定する関数を書きます。表示してよいのは、読み込みが成功したときだけです。
要件
FetchStatusという型エイリアスを定義する- 許す値は
"loading""success""error"の 3 つだけにする - 引数
statusにFetchStatusを付ける - 成功しているときだけ true を返す
入出力例
canShowWorks("loading") → false
canShowWorks("success") → true
canShowWorks("error") → falseヒント
編集 LuaGate編集部