1. test 1
  2. test 2
  3. test 3
コース一覧
TypeScript道場 fleama開発室の10問
不正な状態を型で封じよ

TypeScript道場 fleama開発室の10問

TypeScript入門で身に付けた技を、商店街公式フリマアプリ「fleama」開発室の仕事で試す演習専用コースです。解説はありません。依頼と完成条件だけを読み、白紙から自分で組み立てます。手が止まったときのために、方針・使う構文・部分解の3段階のヒントを各問に用意しています。判定はコンパイラそのものです。型が通らないコードは実行される前に不合格になるので、まず tsc を黙らせてから中身を合わせることになります。基本型の注釈から始まり、関数の署名、any の撲滅、interface の設計、リテラルunion、型ガード、ジェネリクス、入口での変換、入れ子のAPIレスポンスを経て、最後は型のないモジュールを strict で通る形に組み直すところまで、10問で TypeScript の主要な道具を一巡します。1問10分から45分、全10問で約4.5時間です。TypeScript入門を終えて「読めるけれど自分では書けない」と感じている方に向いています。

1
初段
01. 赤い波線を消せ10分
02. 関数に正しい型を付けよ15分
03. このanyを撲滅せよ15分
04. Item型を設計せよ20分
2
中段
01. 不正な状態を型で封じよ25分
02. 型ガードで絞り込め25分
03. 汎用関数に型を付けよ30分
04. 型を付けて事故を防げ30分
3
師範
01. APIレスポンスに型を通せ35分
02. 総合 型のないモジュールを完全TS化45分

不正な状態を型で封じよ

中段 / 目安 25分

朝、開発室に入ると凛さんが画面を睨んでいました。並んでいるのは、fleama の商品状態カラムの実データです。

on_sale / sold / draft / うりきれ / 売り切れ!! / SOLD / on_slae

「事件です。商品状態に『うりきれ』『売り切れ!!』が自由入力されていました。'on_sale' | 'sold' | 'draft' の3つ以外、存在できない世界にしてください」

型を string にしておくと、この世のあらゆる文字列が入れます。「入れてはいけない値」を弾く仕事は、実行時のチェックか、人間の注意力に委ねられます。どちらも、いつか漏れます。

TypeScript にはリテラル union 型があります。型として string ではなく、"on_sale" という文字列そのものを書けるのです。それを縦棒でつなぐと、「この3つのどれか」という型になります。

TypeScript

type ItemStatus = "on_sale" | "sold" | "draft";

こう宣言すると、ItemStatus を受け取る関数に "うりきれ" を渡した瞬間、コンパイルが止まります。実行する前に、テストを書く前に、止まります。凛さんが欲しがっているのはこの静けさです。

もう1つ、おまけの効きめがあります。switch で3つを書き分けたとき、書き忘れた1つを TypeScript が見つけてくれることがあります。戻り値の型を書いておくと、どこにも当たらない経路が残っている場合に「未定義を返す可能性がある」と怒られるからです。型は網羅性のチェックまで肩代わりしてくれます。

完成条件

type ItemStatus をリテラル union 型として定義し、それを受け取って表示用の日本語を返す関数 statusLabel を作ってください。

  • ItemStatus は "on_sale" "sold" "draft" の3つだけを許すこと
  • "on_sale" なら 販売中 を返すこと
  • "sold" なら 売切れ を返すこと
  • "draft" なら 下書き を返すこと
  • 引数の型は string ではなく ItemStatus にすること

進め方

白紙から書いてください。手が止まったらヒントを開けます。ヒントは3段階で、①方針、②使う構文、③部分解の順に出ます。1つも開けずに通せたら、その問題は自分のものです。

書き終えたら、試しに statusLabel("うりきれ") と書いた行を1つ足してみてください。実行する前に赤くなるはずです。それを確認したら、その行は消してから提出してください。赤い波線が残っていると、凛さんのCIは通りません。

要件

  1. type ItemStatus を関数の外で定義すること
  2. ItemStatus は "on_sale" "sold" "draft" の3つだけを許すリテラル union 型にすること
  3. 関数名は statusLabel、引数は ItemStatus を1つ、戻り値は文字列
  4. "on_sale" なら「販売中」、"sold" なら「売切れ」、"draft" なら「下書き」を返すこと
  5. 引数の型を string にしないこと。string にすると不正な値が通ってしまう

入出力例

statusLabel("on_sale") → "販売中" statusLabel("sold") → "売切れ" statusLabel("draft") → "下書き"

ヒント

前のヒントを開くと次が開きます。開かずに解けると未開封クリアです

①方針 先に型の別名を1行で宣言し、そのあとで関数の引数にその名前を使います。関数の中身は3つの値を書き分けるだけです

ヒント 2ヒント 1 を開くと読めます
ヒント 3ヒント 2 を開くと読めます
生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/08/09

関連レッスン

  • 型ガードで絞り込め

    Item | undefined を早期 return で絞り込みます。ガードを消すと本当に赤くなることも自分の手で確かめます。

  • 汎用関数に型を付けよ

    何の配列でも扱える汎用の関数を、型引数で書きます。any に逃げずに1つの関数を全チームの道具にします。

  • 型を付けて事故を防げ

    嘘の型が付いたデータに正直な型を付け直すと、掛け算の行が赤くなります。入口で直してから通します。

  • APIレスポンスに型を通せ

    入れ子になったAPIレスポンスを、as を使わずに型の入れ子で表します。通信の向こう側まで型を届かせます。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • カラムテーブルの「縦の列」
  • TypeScript静的型を加えた JavaScript の上位互換
  • 関数処理に名前を付けて再利用できる単位
  • コンパイルソースをバイトコードへ変換する処理
  • テストバグを見つける工程
  • 戻り値呼び出し元への返答を表す点線矢印
  • 引数位置引数=順番で渡す。
main.ts
学習モード
エディタを読み込んでいます

メモ

不正な状態を型で封じよ

⌘S で保存