IsUnion<T>
T
がunion型かどうかを判断して true
or false
を返す
使用例
tstype case1 = IsUnion<string> // false
type case2 = IsUnion<string|number> // true
type case3 = IsUnion<[string|number]> // false
定義時の考え方
「Union型かどうか?」の判定をしたい
.. extends ..
で条件分岐したいが、直接的にUnion型かどうかを判定する方法がない
そこで「Union型特有の機能はなんだっけ?」を考える
Union型なら .. extends
を使うと分配され、そうでなければ分配されない
分配された個々を、元の型と比較して、同じかどうかを確かめればいい
例えば、Union型以外の時、
分配前は string
、分配後も string
で同じになる
例えば、Union型の時、
分配前の a|b|c
で、分配後は a
で異なるものになる
次に、分配前と分配後を比較する必要がある
しかし、普通に 分配後 extends 分配前
と書くと常に真になってしまう
そこで、反転して書きたい 分配前 extends 分配後
しかし、 a|b|c extends a
の様に書くと、再び a|b|c
が分配されてしまうので困る
結果的に 分配前[] extends 分配後[]
とする
これで判断できる
定義1
tstype IsUnion<T, U = T> =
T extends T ? ([U] extends [T] ? false : true)
: never;
型引数の U
は、「分配前の T
」が欲しいために定義している
定義2
定義1とほぼ同じだが、ちょっとスマート
tstype IsUnion<T> =
T[] extends (T extends T ? T[] : never)
? false
: true;
(..)
の部分は
T[] extends ..
の部分は普通に考えればわかる

定義3
tstype IsUnion<T, U = T> = T extends T ? Not<Equal<T, U>> : never;
定義1とほぼ同じ