LoginSignup
62
22

More than 3 years have passed since last update.

TypeScript: 配列型からその要素のユニオン型を導出する方法。例えば、Array<A | B | C>からA | B | Cを導き出す。

Last updated at Posted at 2019-12-06

本稿では、配列型からその要素のunion型を導き出す方法を説明する。

やりたいこと

例えば、次のList型のように、stringnumberbooleanの要素を持ちうるArray型があるとき、

type List = (string | number | boolean)[]

次のように、配列要素のユニオン型を求めたい。

type Elem = string | number | boolean

やりかた

indexed access operator(T[K]のようなカギカッコ)使うと、配列要素の型を取り出すことができる:

type List = (string | number | boolean)[]
type Elem = List[number] // string | number | boolean になる

コンパイルが通ることを確認するコード:

const el1: Elem = '' // string
const el2: Elem = 0 // number
const el3: Elem = false // boolean

→このコードをTypeScript Playgroundで試す

どうしてList[number]で配列要素のユニオン型が分かるの?

話を単純にするために、要素の型が1つだけの(=ユニオン型ではない)配列型を考えてみよう。次のスニペットのBooleans型はbooleanな値からなる配列型である。

type Booleans = boolean[]

このBooleans型について、いくつか自問自答してみよう。

  • Booleans型の要素0番目の型は何になるか? 要素0番目に代入できる値はtureもしくはfalseなので、答えは「boolean型」である。
  • Booleans型の要素1番目の型は何になるか? これも同様に、答えはboolean型だ。
  • Booleans型の要素2番目の型は? これも当然、boolean型だ。

私達がこの自問自答で要素の型を考えられるように、TypeScriptでも要素の型を調べることができる。それが、indexed access operatorだ。

type Booleans = boolean[]
type TypeOfElement0 = Booleans[0] // 質問「要素0番目の型は何?」をコードで表現したもの
type TypeOfElement1 = Booleans[1] // 質問「要素1番目の型は何?」をコードで表現したもの
type TypeOfElement2 = Booleans[2] // 質問「要素2番目の型は何?」をコードで表現したもの

質問「要素0番目の型は何?」は、実はもっと一般化することができる。それが「要素N番目の型は何?」という質問だ。「N番目」の「N」に対応する、TypeScriptの表現はnumberになる。

type Booleans = boolean[]
type TypeOfElement = Booleans[number] // 質問「要素N番目の型は何?」をコードで表現したもの

ここまでは、要素の型が1種類の配列型であるboolean[]でindexed access operatorを説明してきたが、要素がユニオン型になっている配列にも話を広げてみよう。最初に示した、List型で、先程の自問自答を考えてみることにする。

type List = (string | number | boolean)[]
  • List型の要素0番目の型は何になるか? 要素0番目の値は、stringかもしれないし、numberかもしれないし、booleanかもしれない。だから、答えは「string | number | boolean型」である。
  • List型の要素1番目の型は何になるか? これも同様に、答えはstring | number | boolean型だ。
  • List型の要素2番目の型は? これも当然、string | number | boolean型だ。

つまり、質問を一般化すると、

  • List型の要素N番目の型は? → string | number | boolean型。

になる。これを先程のBooleansの例と同様手順でTypeScriptのコードに起こすと、本稿冒頭の「やりかた」で示したスニペットになるわけだ:

type List = (string | number | boolean)[]
type Elem = List[number] // Elem は string | number | boolean になる
62
22
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
62
22