つくる - 丸ごとTS化完了

移行の終点

この回で新しい知識は出てきません。データ層、ユーティリティ、画面まわりと下から上げてきた 3 つを、1 本の関数につなぎます。React入門で書いたポートフォリオの、表示用のまとめ文を作る部分です。

使うのは第4章の interface、第5章の union と分岐、第6章から続く配列メソッドの型です。

つなぐ相手

もとの JavaScript はこうでした。

function buildPortfolioSummary(works, status) { const titles = works.filter((work) => work.published).map((work) => work.title); return "公開作品は" + titles.length + "件です。" + titles.join("、"); }

動きますが、通信中でも失敗しても同じ文が出ます。作品が 0 件のときは、うしろに何も付かない中途半端な文になります。

形を 2 つ決める

先に型です。作品 1 件の形と、読み込みの状態の 2 つを決めます。

interface Work { id: number; title: string; published: boolean; } type LoadStatus = "loading" | "success" | "error";

LoadStatus を文字列リテラルの union にしておくと、打ち間違いがその場で止まります。

buildPortfolioSummary(works, "succes"); // エラー Argument of type '"succes"' is not assignable to // parameter of type 'LoadStatus'.

status: string にしていたら、この呼び出しは通ってしまい、画面には何も出ないまま原因が分からなくなります。取りうる値が決まっているものは、string ではなく union にする。これが第5章の結論でした。

状態を先に、中身をあとに

分岐の順番は、外側の状態が先です。

if (status === "loading") { return "読み込み中です"; } if (status === "error") { return "読み込みに失敗しました"; }

ここを抜けた時点で、status"success" に絞り込まれています。TypeScript も同じように絞っているので、この先で status にホバーすると "success" とだけ出ます。

残りは中身の話です。公開作品が 1 件も無いときは、件数を並べても意味がないので別の文にします。

手を動かす

引数に型を通し、状態の分岐と 0 件の分岐を足してください。順番はいつもどおり、型を付けてから中身です。

この関数が通ったら、React入門のコードのうち関数とデータ層は、丸ごと TypeScript に載りました。ここで作った WorkLoadStatus は、そのまま次のコースへ持っていきます。

要件

  1. 作品 1 件の形を Work という名前で定義する
  2. 読み込み状態を loadingsuccesserror だけを取る型として定義する
  3. 引数と戻り値に型を付ける
  4. loading のときは 読み込み中です を返す
  5. error のときは 読み込みに失敗しました を返す
  6. success で公開作品が 0 件のときは 公開作品はまだありません を返す

入出力例

buildPortfolioSummary([{"id":1,"published":true,"title":"プロフィールサイト"},{"id":2,"published":false,"title":"自己紹介カード"},{"id":3,"published":true,"title":"スキル一覧の表"}], "success")"公開作品は2件です。プロフィールサイト、スキル一覧の表" buildPortfolioSummary([], "loading")"読み込み中です" buildPortfolioSummary([{"id":1,"published":true,"title":"プロフィールサイト"}], "error")"読み込みに失敗しました" buildPortfolioSummary([{"id":9,"published":false,"title":"下書きメモ"}], "success")"公開作品はまだありません" buildPortfolioSummary([], "success")"公開作品はまだありません" buildPortfolioSummary([{"id":1,"published":true,"title":"プロフィールサイト"},{"id":2,"published":true,"title":"自己紹介カード"}], "success")"公開作品は2件です。プロフィールサイト、自己紹介カード"

ヒント

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

メモ

つくる - 丸ごとTS化完了

⌘S で保存