不正な状態を型で封じよ
中段 / 目安 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は通りません。
要件
- type ItemStatus を関数の外で定義すること
- ItemStatus は "on_sale" "sold" "draft" の3つだけを許すリテラル union 型にすること
- 関数名は statusLabel、引数は ItemStatus を1つ、戻り値は文字列
- "on_sale" なら「販売中」、"sold" なら「売切れ」、"draft" なら「下書き」を返すこと
- 引数の型を string にしないこと。string にすると不正な値が通ってしまう
入出力例
statusLabel("on_sale") → "販売中"
statusLabel("sold") → "売切れ"
statusLabel("draft") → "下書き"ヒント
前のヒントを開くと次が開きます。開かずに解けると未開封クリアです