「TypeScriptの型入門」で手を動かす - その6

本日は「TypeScriptの型入門」の「union型(合併型)」からです。

qiita.com

union型(合併型)

  • ジェネリクスは型のある言語なら普通にある
  • union型を持っている言語は多く無い
    • TypeScriptはunion型のサポートに力を入れている
  • union型は値が複数の型のどれかに当てはまるような型を表している
    • 複数の型を|でつなぐ
      • string | number なら、stringまたはnumber
      • 確かに、javaもこういうふうにはかけないな、何か実現方法あるのかな

union型の絞り込み

  • type HogePiyo = Hoge | Piyoで新しくunion型で定義した場合、そのままでは使いづらい
  • HogeかもしれないしPiyoかもしれないので、無い可能性があるプロパティは参照できない
  • Hoge | Piyoのような型の値が与えられた場合、実行時に判定する必要がある
  • TypeScriptでは適切に型を絞り込んでくれる機能がある
    • if分岐でinでプロパティがあるかを判定する
  • 余計なプロパティがあると、誤判定的な挙動をするので怖い
    • 動かしてみるとHogePiyoにそもそも余計なプロパティを追加できなかったな

typeofを用いた絞込み

  • string === typeof value のように絞り込みができる
    • あれ、これプリミティブ型以外だめだったりしないのかな..
      • 関数の引数に対するバリデーションとか、ラインタイム依存の場合は駄目な気がする。

nullチェック

  • union型がよく使われるのは、nullableな値を扱いたい場合
    • undefinedも
  • string | null なら文字列の値があるかもしれないしnullかもしれない
  • value != null でチェックすると、型を絞り込んでくれる
  • &&||の短絡実行でも型検査してくれる

代数的データ型っぽいパターン

  • プリミティブ型ならいい感じにunion型の絞り込みができるがオブジェクトはできない
  • リテラル型とunion型を組み合わせることで代数的データ型(タグ付きunion)を再現するパターンが推奨

これ、なんか難しいんですよね。

  • 値があるかもしれない無いかもしれないことを表すoption型をTSで表現
    • type Option<T> = Some<T> | None
      • option型はsomeまたはnone、someだと値がある
    • SomeとNoneは共通のtypeプロパティを持っている
      • typeプロパティで someかnoneかを判定する
  • TypeScriptプログラミングにおいて頻出

代数的データ型とは

  • そもそも「代数」とは
    • 特定の数の代わりとして用いられる文字・記号などのこと(wikipediaより)
    • データ型を変数のように文字・記号で足したり引いたりできる型?
  • 代数的データ型とは
    • 「かつ」と「または」で表すことができる型
    • 「または」の型はコンパイラによってもれなくチェックされる必要がる

zenn.dev

うーむ。関数型言語で使われることが多い概念ぽいな。Haskellでの説明がちょこちょこ出てくる。

qiita.com

この記事では、以下と記載

以下の3つを合わせて代数的データ型と呼びます。
1. 列挙型 (他言語のenumに相当)
2. 直積型 (他言語のstructに相当)
3. 直和型 (他言語のunionに相当)

結局は、union型ならnumber | stringのように、numberかstringかどちらかの型である、というのを定義できて、オブジェクトの場合は、ランタイムで型の判定はできないから(型情報はランタイムでは残らない)、リテラル型でtypeプロパティとかを定義して、どの型なのかを擬似的に判定してるよ、ってことなのかな。

で、単純にtypeofでは判定できないので、擬似的に判定する作りが重くなっちゃてるが、TypeScriptの限界だよと、一旦この理解にしておこう。

union型オブジェクトのプロパティ

  • オブジェクト同士のunion型を作った場合、プロパティアクセスの挙動は概ね期待通りの結果となる
    • HogePIyoHogePiyoを取るかたなら、それの共通プロパティfooだけにアクセス可能
    • また、fooプロパティの型は、HogePiyoそれぞれのfooプロパティの型のunion型になる

プレイグラウンドで手を動かす

長かったー!

ちょこちょこ、なんかテンションだかモチベだか下がって、時間かかっちゃったけど、まぁまぁ理解できたかな。

長かったので、途中で分割しても良かったかも。(モチベ維持のために)

次は「never型」から手を動かします!