ユニオンの分配
条件型 T extends U ? X : Y において、T が「裸の型パラメータ(naked type parameter)」である場合、T にユニオン型が渡されると、その条件型はユニオンの各メンバーに個別に適用され、その結果が再びユニオンとして結合される
裸の型パラメータとは、型パラメータ T が他の型(例: T[], Promise<T>, [T], { prop: T } など)でラップされていない状態を指す
ユニオンの分配が行われるケース
code:ts
type Comparable<T> =
T extends Date ? Date | number:
T extends number ? number :
T extends string ? string :
never;
もし T が例えば Date | string というユニオン型だった場合、Comparable<Date | string> は以下のように分配される
Comparable<Date> の評価:
Date extends Date → true なので Date | number
Comparable<string> の評価:
string extends Date → false
string extends number → false
string extends string → true なので string
結果、T がDate | string の場合、Comparable<T> は Date | number | string となる
ユニオンの分配が抑制されるケース
code:ts
type Comparable<T> =
T extends Date ? Date | number:
T extends number ? number :
T extends string ? string :
never;
もし T が例えば Date | string というユニオン型だった場合、Comparable<Date | string> は以下のように評価され、分配されない
[Date | string] extends [Date] の評価:
Date | string 型は Date 型に代入不可なのでfalse
[Date | string] extends [number] の評価:
Date | string 型は number 型に代入不可なのでfalse
[Date | string] extends [string] の評価:
Date | string 型は string 型に代入可能不可なのでfalse
すべての条件が false だったため、結果は never となります。
結果、T が Date | string の場合、Comparable<T> は never となる
#TypeScript