正解かは分かりませんが見解を記します。(2週間ほど経っているので、解決済みでしたらすみません)
仰るような、Distributive conditional types に関しての説明がドキュメントに記載してあり、こちらがほぼ答えになるかと思われます。
Distributive conditional types are automatically distributed over union types during instantiation. For example, an instantiation of T extends U ? X : Y
with the type argument A | B | C
for T
is resolved as (A extends U ? X : Y) | (B extends U ? X : Y) | (C extends U ? X : Y)
.
(Distributive conditional types は、自動的にユニオン型として分配される。たとえば、T extends U ? X : Y
のT
部分がA | B | C
であった場合、(A extends U ? X : Y) | (B extends U ? X : Y) | (C extends U ? X : Y)
と解釈される。)
すなわち、ユニオンを型引数に渡すと、そのユニオンが1つずつ渡されたかのごとく全パターンが網羅される、といったところでしょうか。
これによれば、ご提示いただいた型はこのように言えるかと思います。
typescript
1type isExtended<T, U> = T extends U ? true : false;
2
3type X = isExtended<boolean, true>;
4// これは下記と実質的に同じと見做せる
5type X_2 = (true extends true ? true : false) | (false extends true ? true : false);
boolean
も、true | false
の2値しか無いことを踏まえると、実質的にユニオンと見ることができそうです。
この仕組みが、組み込みのExtract
などでも使用されています。
御存知の通り、"Exclude<T, U>"はT
からU
部分を除いたユニオンを返すというジェネリクスですが、実装はこの様になっています:
typescript
13
4type Exclude<T, U> = T extends U ? never : T;
Exclude<boolean, true>
はもちろんfalse
型となりますが、その実はこの様になっているのでしょう:
typescript
1type Z = Exclude<boolean, true>;
2// これは下記と実質的に同じと見做せる
3type Z_2 = (true extends true ? never : true) | (false extends true ? never : false);
このように考えると、少し納得できたような気がしますが如何でしょうか。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2024/08/04 13:14