Exclude<T, U>はTypeScriptにおいて、ユニオン型から特定の値を除外するためのユーティリティ型です。
当初TypeScriptには、型を他の型から引くための便利な方法がありませんでした。ジェネリックなAPIを作成したり、リファクタリングを行う際には、しばしば「残りの」型、つまり禁止された値を除いたすべての型を取得する必要がありました。手動でユニオンを操作する代わりに、いくつかの類似のインターフェースを維持する必要がありました。
例えば、型'A | B | C'があるが、Bを除いた型を取得する必要があることがよくあります。これは、関数の複雑な入力パラメータを構築したり、許可された値をフィルタリングしたり、動的に型を生成する際にしばしば求められます。
Excludeはこの問題を解決します。その簡略化されたシグネチャは次のとおりです:
type Exclude<T, U> = T extends U ? never : T;
これは、TからUのすべてのメンバーを除外した型を返します。
例:
type Status = 'draft' | 'published' | 'removed'; type UserVisibleStatus = Exclude<Status, 'removed'>; const visible: UserVisibleStatus = 'draft'; // OK
主な特徴:
Excludeを通常の型に使用できますか?ユニオンではなく?
もしTがユニオン型でなく、Uに含まれる場合でもExcludeは機能しますが、結果はneverまたはTとなり、必ずしも直感的ではありません。
Exclude<'a', 'a'> // 結果: never Exclude<'a', 'b'> // 結果: 'a'
Excludeはオブジェクトの構造内の型のすべての出現を削除しますか?
いいえ、Excludeは型のネストされたフィールドを再帰的に通過せず、ユニオンの上位レベルのみで除外を行います。
Excludeはインターフェースやオブジェクト型とどのように機能しますか?
それは型全体を比較し、個々のプロパティではありません。したがって、いくつかのインターフェースのユニオンからExcludeすると、Uと完全に一致するもののみが削除されます。
interface A { x: number }; interface B { y: string }; // Exclude<A|B, B>はAを返します (Bは完全に一致)
Exclude<UserRoles, 'admin'>を使用してユーザーの役割を検証しましたが、Excludeはネストされた構造に適用されないため、'admin:sub'という権限が除外されませんでした。
利点:
欠点:
Exclude<Action, 'delete'>を使用して公開APIを制限することで、危険な操作を除外します。
利点:
欠点: