1. 公開済みの作品
  2. 下書きの作品
  3. もう 1 件の公開済み作品
  4. メモが空の下書き
コース一覧
TypeScript型設計:オブジェクト・状態・ジェネリクス
inと判別で絞り込む

TypeScript型設計:オブジェクト・状態・ジェネリクス

interface、optional property、readonly、union・リテラル型、型ガード、ジェネリクスを扱う全23レッスンの型設計コースです。Profile・Work・ApplicationStateを題材に、APIや画面で扱うデータと状態を壊れにくい型として設計します。既存JavaScriptプロジェクトの移行は次のコースで扱います。

1
オブジェクト型とinterface
01. interface15分
02. 省略可能なプロパティ15分
03. readonly15分
04. interfaceとtype15分
05. ネストした型15分
06. オブジェクト配列15分
07. つくる - Work型とProfile型20分
08. 第4章クイズ15分
2
union・リテラル型・型ガード
01. union型15分
02. リテラル型15分
03. 状態のunion15分
04. typeofで絞り込む15分
05. inと判別で絞り込む15分
06. 状態で表示を切り替える15分
07. つくる - 状態の型表現20分
08. 第5章クイズ15分
3
ジェネリクス入門
01. なぜジェネリクスか10分
02. ジェネリック関数15分
03. 配列を返す汎用関数15分
04. 制約付きジェネリクス15分
05. 組み込みのジェネリクス15分
06. つくる - 汎用フィルタ関数20分
07. 第6章クイズ15分

inと判別で絞り込む

オブジェクトには typeof が効かない

前回は typeof で型を絞り込みました。ところが相手がオブジェクトだと、この手が使えません。

TypeScript

type PublishedWork = { title: string; url: string }; type DraftWork = { title: string; memo: string }; type PortfolioWork = PublishedWork | DraftWork;

公開済みの作品には公開先の url があり、下書きには自分用の memo があります。しかし typeof はどちらに対しても "object" としか答えません。区別できないのです。

in でプロパティの有無を見る

オブジェクトを見分けるときは、そのオブジェクトが特定のプロパティを持っているかどうかで判定します。使うのは in 演算子です。

TypeScript

function workLine(work: PortfolioWork): string { if ("url" in work) { return work.title + " " + work.url; } return work.title + "(下書き)"; }

"url" in work が true の枝では work が PublishedWork に確定するので、work.url を読めます。抜けたあとは DraftWork に確定するので、work.memo を読めます。

絞り込む前に work.url と書くと、当然止まります。

TypeScript

function workLine(work: PortfolioWork): string { return work.url; // エラー Property 'url' does not exist on type 'PortfolioWork'. }

work.title のほうは、どちらの型も持っているので絞り込まなくても読めます。

判別プロパティを置くやり方

プロパティの有無に頼らず、種類を表す目印を最初から入れておく書き方もあります。

TypeScript

type PublishedWork = { kind: "published"; title: string; url: string }; type DraftWork = { kind: "draft"; title: string }; type PortfolioWork = PublishedWork | DraftWork; function workLine(work: PortfolioWork): string { if (work.kind === "published") { return work.title + " " + work.url; } return work.title + "(下書き)"; }

この kind を判別プロパティと呼びます。リテラル型で値を固定してあるので、比較するだけで絞り込みが効きます。

自分で型を設計できるなら判別プロパティを選びます。あとから型を足しても壊れにくいからです。目印を足せない外部データには in を使います。

手を動かす

演習では、公開済みの作品と下書きの作品を見分けて、一覧の 1 行を作ります。型はすでに定義してあるので、絞り込みの分岐を書いてください。

要件

  1. in を使って公開済みか下書きかを見分ける
  2. 公開済みならタイトルと URL を半角スペースでつなぐ
  3. 下書きならタイトルのうしろに (下書き) を付ける
  4. 型の定義は変えない

入出力例

workLine({"title":"プロフィールサイト","url":"https://example.com/profile"}) → "プロフィールサイト https://example.com/profile" workLine({"memo":"配色を検討中","title":"自己紹介カード"}) → "自己紹介カード(下書き)" workLine({"title":"スキル一覧の表","url":"https://example.com/skills"}) → "スキル一覧の表 https://example.com/skills" workLine({"memo":"","title":"配色メモ"}) → "配色メモ(下書き)"

ヒント

`in` は `"プロパティ名" in オブジェクト` の順に書きます

`"url" in work` が true の枝では、`work` は公開済み作品に確定しています

その枝を抜けたあとは下書きに確定しているので、条件を重ねて書く必要はありません

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

関連レッスン

  • 状態で表示を切り替える

    状態別のメッセージ関数を書き、unionと分岐で全パターンを網羅できるようになります。

  • つくる - 状態の型表現

    通信状態まわりを型で固め、不正な状態を型で排除します。

  • 第5章クイズ

    union型・リテラル型・型ガードの理解を確認します。

  • なぜジェネリクスか

    any版の汎用関数で起きる事故を見て、型引数で汎用化する動機を説明できるようになります。

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

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

  • オブジェクトキーと値のペアで構造を作るデータ
  • プロパティメソッドを属性のようにアクセスできるようにするデコレータ。
  • 演算子//は切り捨て除算(7 // 2 = 3)。
  • 設計何をどう作るかを決める前工程
  • URLページの住所全体
main.ts
学習モード
エディタを読み込んでいます

メモ

inと判別で絞り込む

⌘S で保存