0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Conditional Typeの「T extends」を「T[number] extends」と書いてConditional Typeの中でUnion型に変換すると、分配法則が適用されない

Last updated at Posted at 2025-01-30

以下はtype-challengesの「Include」で色々試していた時に気づいたことです。

まず、以下のConditional Typeと呼ばれる構文において、型変数TがUnion型の場合は各々の要素に対してConditionが適用されます。
「Union Distribution」とか「分配法則」と呼ばれるもので、先人の解説記事がたくさんあるので説明は割愛します。

type Condition<T, U> = T extends U ? T : never;
type Test = Condition<'Kars' | 'Esidisi' | 'Wamuu' | 'Santana' | 1, string> // -> 'Kars'|'Esidisi'|'Wamuu'|'Santana'

以上を前提の知識として、次のコードを見てください。

/* _____________ ここにコードを記入 _____________ */

type Includes<T extends readonly any[], U> = T[number] extends U ? true : false;
type Test2 = Includes<['Kars', 'Esidisi', 'Wamuu', 'Santana'], 'Kars'> // -> なぜかfalseになる

/* _____________ テストケース _____________ */

上記のコードにおいて型Test2を求める際、ジェネリクスIncludeのT[number]'Kars' | 'Esidisi' | 'Wamuu' | 'Santana'になるので、分配法則が適用されるならばTest2はtrue | false | false | false、つまりbooleanになるはずです。
しかし、実際はfalseになります。

'Kars' | 'Esidisi' | 'Wamuu' | 'Santana''Kars'に代入できないのでfalseになっていると思われます。つまり、分配法則が適用されません

解決方法はシンプルで、この場合はT[number]を別の型変数に一度代入すれば解決します。例えば、次のコードがその一例になります。

/* _____________ ここにコードを記入 _____________ */

type Source = Readonly<['Kars', 'Esidisi', 'Wamuu', 'Santana']>[number];
type Includes<T, U> = T extends U ? true : false;
type Test3 = Includes<Source, 'Kars'> // -> boolean

/* _____________ テストケース _____________ */

※追記
コメントで気づかされましたが、別に改めて型変数を増やす必要ないですね

/* _____________ ここにコードを記入 _____________ */
type Includes<T, U> = T extends U ? true : false;
type Test2 = Includes<['Kars', 'Esidisi', 'Wamuu', 'Santana'][number], 'Kars'> // -> boolean

/* _____________ テストケース _____________ */

type-challengesをやったことがある方は分かると思いますが、上記のジェネリクスIncludesはchallengesの回答としては誤りです。

参考資料

参考というか、ほぼ回答ですね。この記事で原因が分かりました。ほんと、ありがとうございます。
参考資料では型関数で説明されていますが、Array[number]によるユニオン型でも同様の事象が起きたので、今回書いてみました。

0
0
2

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?