1. test 1
  2. test 2
  3. test 3
  4. test 4
  5. test 5
コース一覧
TypeScript道場 fleama開発室の10問
Item型を設計せよ

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分

Item型を設計せよ

初段 / 目安 20分

凛さんが白板の前に立ちました。書かれているのは、開発室のメンバーそれぞれが書いた「商品」のコードです。ある人は title、ある人は name、ある人は itemName。価格を文字列で持っている人までいます。

「出品データの形が人によってバラバラです。interface Item として正式に定義を。画像URLは省略可能、id は書き換え不可で」

interface は、オブジェクトの形を宣言する道具です。どんなプロパティが、どんな型で入っているのかを1箇所に書いておくと、以後そのオブジェクトを触るすべての場所で TypeScript が形を見張ってくれます。名前を titel と打ち間違えれば、その場で赤くなります。

今回の指定は2つあります。

1つめは省略可能なプロパティです。プロパティ名のうしろに疑問符を1つ付けると、「あってもなくてもよい」という意味になります。ただし strict が効いているので、省略可能なプロパティを読んだ値は「その型、または未定義」として扱われます。そのまま文字列として使うことはできません。存在するかどうかを確かめてから使う必要があります。これは面倒ではなく、事故を1つ潰しているのだと考えてください。

2つめは書き換え不可です。プロパティ名の前に readonly を付けると、代入しようとした時点でコンパイルが止まります。出品IDのように、後から変わってはいけない値に付けます。

完成条件

interface Item を定義し、それを使う関数 itemLabel を作ってください。

Item の中身は次のとおりです。

  • id は数値。書き換え不可
  • name は文字列
  • price は数値
  • imageUrl は文字列。省略可能

itemLabel は Item を1つ受け取り、次の形の文字列を返します。

プレーンテキスト

#12 みかん 380円 画像あり
  • 画像URLがあるときは末尾を 画像あり、ないときは 画像なし にすること
  • 画像URLが空文字のときも 画像なし として扱うこと

進め方

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

interface の宣言は関数の外に書きます。プロパティのあいだの区切りは、セミコロンでも改行だけでもかまいません。

要件

  1. interface Item を関数の外で定義すること
  2. Item は id が数値で書き換え不可、name が文字列、price が数値、imageUrl が文字列で省略可能
  3. 関数名は itemLabel、引数は Item を1つ、戻り値は文字列
  4. 画像URLがあるときは末尾を「画像あり」、ないときや空文字のときは「画像なし」にすること
  5. 「#12 みかん 380円 画像あり」の形の文字列を return で返すこと

入出力例

itemLabel({"id":12,"imageUrl":"https://fleama.example/12.jpg","name":"みかん","price":380}) → "#12 みかん 380円 画像あり" itemLabel({"id":7,"name":"中古スニーカー","price":4200}) → "#7 中古スニーカー 4200円 画像なし" itemLabel({"id":33,"imageUrl":"","name":"手編みマフラー","price":1800}) → "#33 手編みマフラー 1800円 画像なし" itemLabel({"id":1,"imageUrl":"https://fleama.example/1.png","name":"レトロ湯呑み","price":0}) → "#1 レトロ湯呑み 0円 画像あり" itemLabel({"id":205,"name":"商店街トートバッグ","price":990}) → "#205 商店街トートバッグ 990円 画像なし"

ヒント

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

①方針 先に interface で形を宣言し、そのあとで関数の引数の型にその名前を書きます。関数の中では画像URLの有無を判定して末尾の言葉を決め、最後に1本の文字列に組み立てます

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

関連レッスン

  • 不正な状態を型で封じよ

    商品状態を3つのリテラルの union にし、それ以外が存在できない世界にします。typo が実行前に死にます。

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

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

  • このanyを撲滅せよ

    散らばった any を消します。推論に任せられる箇所は、あえて書かないことも腕前のうちです。

  • 関数に正しい型を付けよ

    手数料計算の関数に、引数と戻り値の型を付けます。署名を読めば中身を読まなくて済む形にします。

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

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

  • URLページの住所全体
  • オブジェクトキーと値のペアで構造を作るデータ
  • プロパティメソッドを属性のようにアクセスできるようにするデコレータ。
  • TypeScript静的型を加えた JavaScript の上位互換
  • コンパイルソースをバイトコードへ変換する処理
  • 関数処理に名前を付けて再利用できる単位
  • interface実装を持たないメソッド契約。複数 implements 可
  • 引数位置引数=順番で渡す。
main.ts
学習モード
エディタを読み込んでいます

メモ

Item型を設計せよ

⌘S で保存