VIDEO LESSON
TypeScriptの実践的な型設計:ユニオン・satisfies・unknownの使い分けの解説動画
再生時間 7:43動画を別のタブで開く ↗
動画の字幕・文字起こしを読む
再生中の字幕を濃い黒で表示し、一番上に追従します。字幕の行を選ぶと、その位置から再生できます。
- 0:00こんにちは。
- 0:00今回のテーマは、タイプスクリプトの実践的な型設計です。
- 0:05状態の違いをユニオン型で表し、設定をサティスファイズで確かめ、外部データをアンノウンで受けて検証する、
- 0:10三つの道具の使い分けを学びます。
- 0:15舞台は、記事を取得して画面に表示する小さなプログラムです。
- 0:20大切な区別は、型チェックで確かめることと、実行時に確かめることは別だ、という点です。
- 0:26画面の状態や、コードの中で作る設定は型で守れますが、通信で届くデータの中身は、
- 0:30実行時に調べなければ分かりません。
- 0:35この線引きを意識しながら、矛盾した状態を作らない、書き間違いを早く見つける、
- 0:41危ないデータを入口で止める、という三つの効果を順に確認していきましょう。
- 0:46まず、記事そのものを表すポスト型を用意します。
- 0:50文字列のアイディーとタイトルを持つ、シンプルな形です。
- 0:54次に読み込み状態を、真偽値のローディングと、任意のデータとエラーで表してみます。
- 1:01一見便利ですが、この形では、読み込みが終わっているのにデータとエラーを両方持つ、
- 1:07といった矛盾した組み合わせまで型チェックを通ってしまいます。
- 1:12実機でも、その矛盾したオブジェクトがエラーなく作れることを確認しました。
- 1:18画面側で条件分岐を増やして取り繕う前に、そもそも許可する状態の組み合わせを、
- 1:22型の側で絞ることが大切です。
- 1:27次から、そのための書き方を見ていきます。
- 1:30解決策は、判別可能なユニオンです。
- 1:33ロードステート型は、待機中、読み込み中、成功、失敗の四つの形の、どれか一つだけを表します。
- 1:40四つに共通するステータスには、それぞれ違う文字列を入れます。
- 1:46成功の形だけが記事データを持ち、失敗の形だけがメッセージを持ちます。
- 1:51逆に言えば、成功なのにデータがない値は、この型には代入できません。
- 1:57実機でも、データなしの成功状態はエラー・ティーエス2322になることを確認しました。
- 2:04状態と、その状態で必要なデータをひも付けることで、あり得ない組み合わせ自体を作れなくするのが、
- 2:09この設計の狙いです。
- 2:14ロードステートを使う関数、ゲットラベルを見てみましょう。
- 2:19ステータスでスイッチ分岐すると、各ケースの中では型が自動で絞り込まれます。
- 2:25成功のケースではデータが必ずあると判断されるため、タイトルをそのまま読めます。
- 2:31感嘆符を付けて無理に断言する書き方は要りません。
- 2:35待機中なら記事を選んでください、読み込み中なら読み込み中、失敗ならそのメッセージを返す、
- 2:41というように、状態ごとに返せる値が決まります。
- 2:46実機で四つの状態すべてを渡すと、記事を選んでください、読み込み中、型設計の基本、
- 2:52読み込みに失敗しました、の順に表示され、記事の説明と一致しました。
- 2:59分岐の漏れを防ぐ仕掛けが、ネバーです。
- 3:01ゲットラベルのデフォルトでは、アサートネバーという関数へ値を渡します。
- 3:07この関数はネバー型の引数しか受け取りません。
- 3:10通常はすべてのケースを処理し終えるため、デフォルトに残る値はない、つまりネバーになるはずです。
- 3:17ところが新しい状態キャンセルドを追加して分岐を書き忘れると、残った値がネバーではないため、
- 3:22エラー・ティーエス2345が発生します。
- 3:27実機でも同じエラーを確認しました。
- 3:30状態を増やしたときに、直すべき場所をコンパイラが教えてくれるわけです。
- 3:35ただしこれはコード内の分岐漏れの検出であり、外部データの正しさを保証するものではありません。
- 3:42次は設定の検査です。
- 3:43ルート設定では、ホームは文字列のパス、記事一覧はパスと認証要否を持つオブジェクト、
- 3:48というように、キーごとに値の形が違います。
- 3:53ここでサティスファイズ・レコード・ページネーム・ルート、と書くと、キーがそろっているか、
- 3:59各値がルート型を満たすかを、コンパイル時に確かめられます。
- 4:04キーを打ち間違えた場合や、数値のような合わない値を入れた場合も、エラーになることを実機で確認しました。
- 4:12そのうえで、ホームは文字列として、アーティクルズはオブジェクトとして、そのまま扱えます。
- 4:19実行すると、ホームはスラッシュのまま、アーティクルズのパスは大文字に変換されて表示されます。
- 4:26型注釈との違いも押さえます。
- 4:28コロンでレコード型を注釈すると、値はその型で広く扱われ、各項目は文字列かオブジェクトか分からないルート型になります。
- 4:38そのため、文字列のメソッドを呼ぶ前に絞り込みが必要になり、実機でもエラー・ティーエス2339を確認しました。
- 4:46一方サティスファイズは、検査をしながら、書いた値本来の扱いやすさを残します。
- 4:52ただし、サティスファイズはコンパイル時の検査だけです。
- 4:57実行時の検証や、オブジェクトの凍結はしませんし、すべての値がリテラル型のまま残るわけでもありません。
- 5:04読み取り専用やリテラルとして固定したい場合は、別の仕組みと役割を分けて考えてください。
- 5:11三つ目は、外部データの扱いです。
- 5:14エーピーアイの応答は、型定義を書いただけでは保証されません。
- 5:18そこでパースポスト関数は、引数をアンノウンで受けます。
- 5:22アンノウンは、何が入っているか分からない、という型です。
- 5:26確認せずにタイトルなどを読もうとすると、エラー・ティーエス18046になり、
- 5:30実機でも確認しました。
- 5:34関数の最初では、タイプオブでオブジェクトかどうかを調べ、ヌルと配列を除外します。
- 5:40どれかに当てはまらなければ、記事データはオブジェクトである必要があります、
- 5:43というエラーを投げます。
- 5:47このように、入口で疑ってかかることが、安全な受け取りの第一歩です。
- 5:52続いて、プロパティの中身を確認します。
- 5:54イン演算子でアイディーとタイトルがあるかを調べ、タイプオブでどちらも文字列かを確認します。
- 6:01通らなければ、エラーを投げます。
- 6:03最後は、確認できた二つだけを取り出した、新しいオブジェクトを作って返します。
- 6:08余分な項目をそのまま通さない点もポイントです。
- 6:11フェッチポストでは、まずレスポンス・オッケーを確認し、失敗ならステータス付きのエラーを投げます。
- 6:18通信の結果はアンノウンとして受け取り、パースポストへ渡します。
- 6:22なお空文字の禁止や長さの制限は、型でもこの関数でも自動では決まらないため、
- 6:26必要なら別途追加してください。
- 6:29最後に、二つの仕組みをつなぎます。
- 6:32トゥーロードステート関数は、アンノウンの入力をパースポストで検証し、成功すればデータを持つサクセス状態を、
- 6:37失敗すればメッセージを持つエラー状態を返します。
- 6:43例外の受け取りでも、エラーの型はアンノウンとして扱い、エラーかどうかでメッセージの取り方を分けます。
- 6:50実機で試すと、正しい入力では見出しとして型設計の基本が表示され、アイディーが数値の入力では、
- 6:56文字列である必要があります、というメッセージが表示され、記事の期待どおりでした。
- 7:03検証と状態管理を組み合わせると、画面側は迷わず表示を切り替えられます。
- 7:08まとめです。
- 7:08状態ごとに必要なデータが変わるなら判別可能なユニオン、分岐漏れの検出にはネバー、
- 7:12コード内で作る設定の確認にはサティスファイズ、外部入力にはアンノウンと実行時の検証、
- 7:16という使い分けです。
- 7:20実行手順は、記事の五つのファイルを保存し、ストリクトなどを付けたコマンドでコンパイルして、
- 7:24生成されたジャバスクリプトを実行します。
- 7:28練習として、キャンセルドという状態を追加して分岐漏れのエラーを見つけたり、
- 7:32タイトルの空文字を禁止する検証を足したりしてみてください。
- 7:36型で守れる範囲と、実行時に確かめる範囲を分けて考える習慣が、実践的な型設計の第一歩です。
- 7:41お疲れさまでした。
この動画で学べること
TypeScriptの実践的な型設計をコードで解説。判別可能なユニオンによる状態管理、neverの分岐漏れ検出、satisfiesによる設定の型検査、unknownを使ったAPI応答の検証を学べます。TypeScript 4.9以降に対応。
解説記事・サンプルコードを読む:TypeScriptの実践的な型設計:ユニオン・satisfies・unknownの使い分け →