VIDEO LESSON

TypeScriptのユニオン型と型ガード:型の絞り込みからneverによる網羅チェックまでの解説動画

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

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

  1. 0:00こんにちは。
  2. 0:00タイプスクリプト入門、第六回はユニオン型と型ガードです。
  3. 0:05前回は関数の型を学びました。
  4. 0:07今回は、一つの値が複数の型を取り得る場合に、型を安全に扱う方法を学びます。
  5. 0:14キーワードは三つです。
  6. 0:15候補を列挙するユニオン型、候補を減らす絞り込み、そして絞り込みの仕組みである型ガードです。
  7. 0:23さらに、外部から届いた不明な値を検証する方法と、処理漏れをコンパイル時に見つけるネバーの使い方まで、
  8. 0:28配送状態を題材に順に確認します。
  9. 0:34この回を終えるころには、状態ごとに必要なデータが違うデータを、型で安全に表せるようになります。
  10. 0:41型は実行時には残りませんが、書いている最中とコンパイルの段階で、間違いを早く見つける助けになります。
  11. 0:50まずユニオン型です。
  12. 0:51ユニオン型は、値が取り得る型を縦棒でつないで列挙したものです。
  13. 0:56たとえば文字列か数値、という変数は、文字列と数値のどちらも代入できますが、
  14. 1:01それ以外の真偽値などを入れようとすると型エラーになります。
  15. 1:06大切なのは、ユニオン型の値には、すべての候補に共通する操作しか、そのままでは使えないことです。
  16. 1:14文字列専用のメソッドを呼ぼうとするとエラーになります。
  17. 1:18何でも許すエニー型に変えてしまえばエラーは消えますが、存在しないメソッドを呼ぶ誤りも見つけられなくなります。
  18. 1:27候補を絞ってから使う、というのが基本の流れです。
  19. 1:30候補を絞る代表的な方法が、タイプオブによる判定です。
  20. 1:35参照番号を整形する関数で見てみましょう。
  21. 1:38この関数は、文字列か数値を受け取り、文字列を返します。
  22. 1:42タイプオブで数値かどうかを判定し、数値なら数値専用のメソッドで丸めて表示します。
  23. 1:49そうでなければ、文字列として空白を取り除き、大文字に変換します。
  24. 1:54呼び出し結果は、数値の四十二がナンバー四十二、空白付きの文字列が大文字に整えられて表示されます。
  25. 2:02判定の中でだけ、その型専用の操作が安全に使える点に注目してください。
  26. 2:08なお、数値であることは、業務上正しい番号であることとは別です。
  27. 2:13必要なら整数かどうかなどを別途検証しましょう。
  28. 2:16このように、判定や処理の流れから型の候補を減らすことを、型の絞り込みと呼びます。
  29. 2:22ポイントは、早期にリターンする書き方です。
  30. 2:25数値の分岐でリターンした後は、その先のコードでは数値の可能性が消え、残る候補は文字列だけになります。
  31. 2:32コンパイラはこの流れを追って、候補を自動で減らしてくれます。
  32. 2:36そして、タイプオブのように型を判定する仕組みそのものを、型ガードと呼びます。
  33. 2:41等しいかどうかの比較や、値があるかどうかの確認も、絞り込みとして働きます。
  34. 2:46絞り込みは特別な記法ではなく、普段の条件分岐の中で起きていることなのです。
  35. 2:51次に、状態とデータを組み合わせる方法です。
  36. 2:55配送の状態を、単なる文字列と、任意の宛先やエラー文で表すと、配送成功なのに宛先がない、
  37. 3:01という矛盾したデータも作れてしまいます。
  38. 3:06そこで、状態ごとにオブジェクトの形を分けます。
  39. 3:10配送待ちには追加のデータはなし、送信済みには宛先が必須、失敗には理由が必須、
  40. 3:18という三つの形を用意し、共通のステータスには、それぞれ異なる文字列リテラルを指定します。
  41. 3:25このように、判別に使う共通プロパティを持つユニオン型を、判別可能なユニオンと呼びます。
  42. 3:33状態と必要なデータを、型のレベルで結び付けられるのが利点です。
  43. 3:38この形なら、コンパイラが状態とデータの正しい組み合わせを覚えてくれます。
  44. 3:45判別可能なユニオンは、スイッチ文と相性がよい書き方です。
  45. 3:49ステータスで分岐すると、各分岐の中では、その状態のオブジェクトだけが候補に残ります。
  46. 3:56送信済みの分岐では宛先を、失敗の分岐では理由を、そのまま安全に読み取れます。
  47. 4:02逆に、別の状態のプロパティを無条件に読もうとすると型エラーになります。
  48. 4:08状態とデータの取り違えを、コンパイル時に見つけられるわけです。
  49. 4:13表示の文言は状態ごとに決まります。
  50. 4:16配送待ち、宛先付きの配送完了、理由付きの配送失敗です。
  51. 4:20分岐を書く側も読む側も、今どの状態を扱っているかが明確になります。
  52. 4:25すべての状態を処理した後のデフォルト分岐には、残る候補がありません。
  53. 4:31その、値が存在しないことを表す型がネバーです。
  54. 4:34この性質を網羅チェックに使います。
  55. 4:36デフォルトでは、ネバー型の引数だけを受け取る関数を呼びます。
  56. 4:41もし新しい状態、たとえば再試行中を追加したのに分岐を足し忘れると、デフォルトにその状態が残ってしまい、
  57. 4:47ネバーを期待する場所に渡せなくなって型エラーになります。
  58. 4:53つまり、処理漏れを実行前にコンパイルエラーとして教えてくれる仕組みです。
  59. 4:58状態を増やすときの安全網として、ぜひ覚えておきましょう。
  60. 5:02外部から届いた値は、型が不明なアンノウンとして受け取るのが安全です。
  61. 5:08そのままでは使えないため、検証してから型を付けます。
  62. 5:12ここで使うのが、独自の型ガードです。
  63. 5:16戻り値の型に型述語を書くと、真を返したときに、その値が宣言した型であるものとして絞り込めます。
  64. 5:24配送状態の検証では、まずオブジェクトであることとヌルでないことを確かめ、
  65. 5:30ステータスがあるかを確認し、状態ごとに必要な項目が文字列で存在するかまで調べます。
  66. 5:37ただし型述語は、実装が正しいという前提で動きます。
  67. 5:41検証の書き間違いはコンパイラには証明できないため、不足した項目やヌルなどのテストも必要です。
  68. 5:49では、実際に動かして確かめましょう。
  69. 5:52不明な値の配列に、正しい三つの状態と、宛先が欠けたデータと、ヌルを用意します。
  70. 5:59一つずつ検証し、配送状態として認められたものだけを表示関数に渡します。
  71. 6:05結果は、配送待ち、宛先付きの配送完了、理由付きの配送失敗の順に表示され、
  72. 6:11宛先が欠けたデータとヌルは、不正な配送状態として拒否されます。
  73. 6:17ここで、型を断定するアズだけでは、この検証は実行されません。
  74. 6:22断定はコンパイラへの言い切りであり、実行時のチェックにはならないからです。
  75. 6:28検証を通った値だけが、安全な表示処理へ進めます。
  76. 6:33コンパイルはストリクトを有効にして行い、生成されたジャバスクリプトをノードで実行して確認しました。
  77. 6:41よくある落とし穴も押さえておきましょう。
  78. 6:44第一に、値そのもので判定すると、空文字やゼロも一緒に除外されてしまいます。
  79. 6:49値がない場合だけを除きたいなら、ヌルとアンディファインドを明示的に判定します。
  80. 6:54第二に、ヌルのタイプオブはオブジェクトになります。
  81. 6:58プロパティに触れる前に、ヌルを先に除外してください。
  82. 7:01第三に、イン演算子は継承したプロパティにも反応します。
  83. 7:05形の確認と、自分のプロパティだけを許可する厳密な検証は、目的が違う点に注意しましょう。
  84. 7:11そして、非ヌルアサーションで警告だけを消すと、値がない場合の扱いという判断がコードに残りません。
  85. 7:17決めた扱いを、コードとして書きましょう。
  86. 7:20まとめです。
  87. 7:21ユニオン型は候補を縦棒で列挙し、各候補に固有の操作は、タイプオブなどの型ガードで絞り込んでから使います。
  88. 7:29判別可能なユニオンでは、状態ごとに必要なデータを結び付け、スイッチの各分岐で安全に読み取れます。
  89. 7:37すべての分岐を処理した後に残るネバーを使えば、新しい状態の処理漏れをコンパイルエラーとして検出できます。
  90. 7:45外部入力はアンノウンで受け取り、型述語を持つ検証を通してから使います。
  91. 7:51型による確認と、実行時の検証は別のものだという区別も大切です。
  92. 7:56次回は第七回として、ジェネリクスを学びます。
  93. 7:59お疲れさまでした。
日本語字幕をダウンロード(WebVTT)

この動画で学べること

TypeScriptのユニオン型と型ガードを配送状態の実装で解説。typeof、unknownの検証、判別可能なユニオン、neverによる処理漏れの確認を学びます。

解説記事・サンプルコードを読む:TypeScriptのユニオン型と型ガード:型の絞り込みからneverによる網羅チェックまで →