状態のunion

画面には状態がある

ゆめさくのポートフォリオ一覧は、サーバーから作品データを取ってきて表示します。取ってくるあいだ画面は空っぽで、取り終わったら一覧が出て、失敗したらエラーが出ます。この 3 つの状況を、通信状態と呼びます。

JavaScript ではよく、真偽値を並べて表していました。

let isLoading = true; let hasError = false;

この持ち方には穴があります。isLoadinghasError が両方 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 を自分で定義して、作品一覧を表示してよい状態かどうかを判定する関数を書きます。表示してよいのは、読み込みが成功したときだけです。

要件

  1. FetchStatus という型エイリアスを定義する
  2. 許す値は "loading" "success" "error" の 3 つだけにする
  3. 引数 statusFetchStatus を付ける
  4. 成功しているときだけ true を返す

入出力例

canShowWorks("loading")false canShowWorks("success")true canShowWorks("error")false

ヒント

生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア
編集 LuaGate編集部
main.ts
main.ts
学習モード

メモ

状態のunion

⌘S で保存