0Pricing
TypeScript Academy · レッスン

分配条件型

条件型がユニオンに対してどのように分配されるかを制御します。

「分配条件型」はCoddyKit上の無料TypeScript Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはTypeScript Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 TypeScript Academyコースには全4レッスンが含まれています。

驚くべき動作

条件型には、特別なルールが1つあります。チェック対象の型が裸の型パラメーターで、そこにユニオンを渡すと、条件型は各メンバーに個別に分配され、その結果がユニオンになります。

これは Exclude、Extract、その他多くのユーティリティ型の基盤です。

type ToArray<T> = T extends unknown ? T[] : never;

type A = ToArray<string | number>;
// string[] | number[]  (NOT (string | number)[])

「naked」の意味

「naked」とは、型パラメーターが extends の左側に、別の型でラップされず単独で現れることを意味します。分配が起きるのは、裸のパラメーターの場合だけです。

type Naked<T> = T extends string ? "y" : "n";
// T is naked -> distributes over unions

分配をステップごとに見る

ToArray<string | number> では、コンパイラーは各メンバーを評価します。

  • ToArray<string> = string[]
  • ToArray<number> = number[]

その後、それらをユニオンにします:string[] | number[]。

type R = ToArray<boolean>;
// boolean is true | false, so:
// true[] | false[]

ユニオンをフィルタリングする

分配によって、フィルタリングが簡単になります。不要なメンバーを never に変換すると、never はユニオンから消え、残したメンバーだけが残ります。

type Strings<T> = T extends string ? T : never;

type A = Strings<string | number | boolean>; // string

ユニオンでは never が消える

重要なポイントは、X | never が X に簡約されることです。そのため、分配された分岐が never を生成すると、そのメンバーは最終的なユニオンから実質的に取り除かれます。

type A = string | never;        // string
type B = "a" | never | "b";     // "a" | "b"

分配を無効にする

ユニオン全体を1つの単位として比較する場合など、分配を望まないことがあります。その場合は、両辺を1要素のタプルでラップします:[T] extends [U]。これで T は裸ではなくなるため、分配が無効になります。

type IsNever<T> = [T] extends [never] ? true : false;

type A = IsNever<never>;  // true
type B = IsNever<string>; // false

ラップで機能する理由

左側に [T] を置くと、チェック対象の型は裸のパラメーターではなくタプルになります。特別な分配ルールが適用されなくなり、ユニオン全体が1つの型としてテストされます。

type AllStrings<T> = [T] extends [string] ? true : false;

type A = AllStrings<"a" | "b">;     // true
type B = AllStrings<"a" | number>;  // false

分配ありと分配なし

2つの形式を直接比較してみましょう。裸の形式は各メンバーをチェックし、ラップした形式はユニオンを1つの型としてチェックします。

type Distributed<T> = T extends string ? true : false;
type Wrapped<T> = [T] extends [string] ? true : false;

type A = Distributed<string | number>; // boolean (true | false)
type B = Wrapped<string | number>;     // false

Exclude の内部

組み込みの Exclude<T, U> は、U に代入可能なメンバーを T から取り除きます。これは、一致するメンバーを never に変換する分配条件型にすぎません。

type MyExclude<T, U> = T extends U ? never : T;

type A = MyExclude<"a" | "b" | "c", "b">; // "a" | "c"

Extract の内部

Extract<T, U> はその反対です。U に代入可能なメンバーだけを残します。同じ分配を使いますが、分岐の役割が逆です。

type MyExtract<T, U> = T extends U ? T : never;

type A = MyExtract<"a" | "b" | "c", "a" | "c">; // "a" | "c"

実践的な威力

分配を使うと、1つの式でユニオンのすべてのメンバーを変換できます。各メンバーの配列を作ったり、すべての文字列にプレフィックスを付けたり、形状でフィルタリングしたりできます。ユニオン全体をチェックする [T] extends [U] と組み合わせることで、分配を正確に発生させるタイミングを制御できます。

表記: 実際の TypeScript では、テンプレートリテラル型を、ドル記号と中かっこの穴を含むバッククォートで区切られた文字列として記述します。これらのスニペットでは、そのパターンを Tpl<...> として示し、各部分を順番に並べています。たとえば、リテラルのプレフィックスに続いて Rest に一致するバッククォートテンプレートは、Tpl<'prefix', infer Rest> として表します。

type Prefix<T extends string> = T extends unknown ? Tpl<'id_', T> : never;
// Tpl<'id_', T> is the template literal type joining 'id_' with each T

type A = Prefix<'a' | 'b'>; // 'id_a' | 'id_b'

理解度チェック

分配条件型について、理解度を確認しましょう。

まとめ

分配条件型は、ユニオン用ユーティリティの原動力です。

  • 裸の T extends U ? は、各ユニオンメンバーに対して分配されます。
  • never を返す分岐によって、メンバーをフィルタリングできます。
  • [T] extends [U] は、ユニオン全体のチェック時に分配を無効にします。
  • Exclude と Extract は、小さな分配条件型です。

次のコース22では、型システムで算術を扱います。

よくある質問

「分配条件型」レッスンは無料ですか?

はい。「分配条件型」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、TypeScript Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 TypeScript Academyコースには全4レッスンが含まれています。

「分配条件型」で何を学びますか?

条件型がユニオンに対してどのように分配されるかを制御します。 ブラウザで直接実行するハンズオンコードでTypeScript Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

TypeScript Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのTypeScript Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「分配条件型」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このTypeScript Academyレッスンでコードを書いて実行できますか?

はい。すべてのTypeScript Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 計算言語としての型
  2. 型レベルの条件分岐
  3. 型レベルの再帰
  4. 分配条件型
← TypeScript Academyに戻る