VIDEO LESSON

TypeScriptの実践的な型設計:ユニオン・satisfies・unknownの使い分けの解説動画

再生時間 7:43動画を別のタブで開く ↗
動画の字幕・文字起こしを読む

再生中の字幕を濃い黒で表示し、一番上に追従します。字幕の行を選ぶと、その位置から再生できます。

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

この動画で学べること

TypeScriptの実践的な型設計をコードで解説。判別可能なユニオンによる状態管理、neverの分岐漏れ検出、satisfiesによる設定の型検査、unknownを使ったAPI応答の検証を学べます。TypeScript 4.9以降に対応。

解説記事・サンプルコードを読む:TypeScriptの実践的な型設計:ユニオン・satisfies・unknownの使い分け →