Unionを使うとNumberやStringみたいに型全体でなくても、特定の文字列などの集合で型を作れて便利ですよね。
例えば以下のようなケースがあります。Number型ではなく、ステータスコードだけのための型を作ることができます。
type HttpStatus = 200 | 201 | 400 | 401 | 403 | 404 | 500;
しかし、このような時に特定のコードだけを受け付ける型がほしい場合、以下のように定義する必要が出てきます。
type SuccessStatus = 200 | 201;
もちろん以下のように最初から分けて定義をしていたら良いのですが、仕事をする中でなるべく多くの影響範囲は作りたくないものです。
type SuccessStatus = 200 | 201;
type ClientStatus = 400 | 401 | 403 | 404;
type ServerStatus = 500;
type HttpStatus = SuccessStatus | ClientStatus | ServerStatus;
Exclude
そんな時に使えるユーティリティ型がExcludeです。
以下のような書き方で書くことができます。
type HttpStatus = 200 | 201 | 400 | 401 | 403 | 404 | 500;
type SuccessStatus = Exclude<HttpStatus, 400 | 401 | 403 | 404 | 500>;
// 200 | 201
function handleSuccess(status: SuccessStatus) {
// 200か201のケースのみを処理
}
ソースコード
TypeScriptのソースコードを見てみるとExcludeはこのようなロジックで構成されています。
extends
を用いての実装なんですね
/**
* Exclude from T those types that are assignable to U
*/
type Exclude<T, U> = T extends U ? never : T;