Exclude<T, U> Exclude(Extract を含む)
最終更新:2026-10-22
Exclude<T, U> Exclude(Extract を含む)
Exclude<T, U> はユニオン型 T から「U に代入可能な」メンバーを取り除きます。大きなユニオンから関心のない分岐を切り落とすのによく使われます。その逆の操作である Extract<T, U> は、U に代入可能なメンバーだけを残します。どちらも条件型の分配の性質に基づいています。
| グループ | ユーティリティ型 |
|---|---|
| 種類 | 型 |
| strict モード | 不要 |
ℹ️ 説明 エディタは TypeScript を JavaScript にトランスパイルして実行します(型チェックなし)。型チェック結果は各サンプルの出力を参照してください。
📝 構文
type Exclude<T, U> = T extends U ? never : T;
type Extract<T, U> = T extends U ? T : never;
// 使い方
type PassiveEvent = Exclude<EventType, "click" | "keydown">;
type Interactive = Extract<EventType, "click" | "keydown">;
⚙️ パラメータ
| T | 元のユニオン型です。メンバーが1つずつ条件の判定に参加します(分配律) |
|---|---|
| U | ナローイングの条件です。U に代入可能なメンバーは Exclude では取り除かれ、Extract では残されます |
戻り値:新しいユニオン型です。Exclude は T から U を引いた差集合、Extract は T と U の共通部分です。
▶ サンプル
下のコードを編集して「試す」を押すと、トランスパイル実行結果を確認できます:
出力:
focus | scroll | wheel
click | keydown
(トランスパイル後の実行出力。型レベルの効果としては、passiveEvents に "click" を push するとコンパイルエラーになります。Exclude によって PassiveEvent からすでに取り除かれているからです)
💡 ポイント
ℹ️ 説明 原理は「分配条件型」です。T がユニオンのとき、T extends U はメンバーごとに判定して結果を結合します。U に合致したメンバーは never になり(ユニオンから消える)、これが「取り除き」の実装です。
⚠️ 注意 この2つのツールはユニオン型に対してのみ意味があります。オブジェクト型に直接使うと(T がユニオンでない場合)プロパティごとの処理にならず、直感に反する振る舞いをします。オブジェクトのプロパティの操作には Omit/Pick を使いましょう。
💡 ヒント NonNullable<T> はまさに Exclude<T, null | undefined> の専用の別名です。この関係を覚えておけば、Exclude の理解をそのまま移すことができます。
🏷️ 関連ユーティリティ型
💡 関連ケース
ケースは今後追加予定です。
📚 関連チュートリアル
❓ よくある質問
Q Exclude と Omit の違いは何ですか?
A Exclude はユニオン型の「メンバー」を操作し、Omit はオブジェクト型の「プロパティのキー」を操作します。Omit の内部はまさに Exclude で実装されています。Exclude<keyof T, K> でキーを取り除いてから Pick します。一方はメンバーを、他方はキーを扱います。
Q なぜ「分配」と呼ぶのですか? 分配しないとどうなりますか?
A 分配しない場合、T extends U は "click"|"focus"|... というユニオンを1つのまとまりとして U と比較します。全体は U に代入できないため、何も取り除けません。分配は各メンバーを個別に判定します。これこそユニオンのメンバーを1つずつ「選別する」仕組みです。
Q Exclude はオブジェクトのメンバーも取り除けますか?
A できます。メンバーの型が U に代入可能であればよいのです。たとえば type Shape = Circle | Square のとき type RoundOnly = Exclude<Shape, Square>; とすれば Square が取り除かれます。判定基準は常に「代入可能性」で、リテラルの一致だけではありません。