# TypeScript `Exclude` and `Extract`

`Exclude` and `Extract` are built-in utility types that operate on **Union Types**. They allow you to filter unions by either removing specific members or keeping only specific members.

## 1. `Exclude<UnionType, ExcludedMembers>`

`Exclude` constructs a type by excluding from `UnionType` all union members that are assignable to `ExcludedMembers`.

*   **Mental Model:** "Remove these specific types from the list."

### Basic Example

```typescript
type Status = "success" | "warning" | "error" | "info";

// Remove "warning" and "info"
type CriticalStatus = Exclude<Status, "warning" | "info">;
// type CriticalStatus = "success" | "error"
```

### Removing `null` and `undefined`

While `NonNullable` is usually preferred, `Exclude` can also do this.

```typescript
type MaybeString = string | number | null | undefined;

type JustValues = Exclude<MaybeString, null | undefined>;
// type JustValues = string | number
```

### Excluding Shapes

You can exclude types based on shape compatibility.

```typescript
type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number }
  | { kind: "triangle"; base: number };

// Remove the circle
type AngularShapes = Exclude<Shape, { kind: "circle" }>;
// type AngularShapes = { kind: "square"... } | { kind: "triangle"... }
```

## 2. `Extract<Type, Union>`

`Extract` is the opposite of `Exclude`. It constructs a type by extracting from `Type` all union members that are assignable to `Union`.

*   **Mental Model:** "Keep only these types from the list." (Intersection of two unions).

### Basic Example

```typescript
type Status = "success" | "warning" | "error" | "info";

// Keep only "error" and "warning"
type BadStatus = Extract<Status, "error" | "warning">;
// type BadStatus = "warning" | "error"
```

### Finding Common Types

If you have two unions, `Extract` finds the overlap.

```typescript
type A = "a" | "b" | "c";
type B = "b" | "c" | "d";

type Common = Extract<A, B>;
// type Common = "b" | "c"
```

## 3. How they work

Both utilities rely on **Distributive Conditional Types**.

```typescript
// Exclude implementation
type Exclude<T, U> = T extends U ? never : T;

// Extract implementation
type Extract<T, U> = T extends U ? T : never;
```

When `T` is a union (e.g., `"a" | "b"`), TypeScript distributes the condition:
1.  Is `"a"` assignable to `U`?
2.  Is `"b"` assignable to `U`?

If the result is `never`, that member is removed from the final union.

[[programming/javascript/typescript/typescript]]
[[programming/javascript/typescript/utility-types]]
[[programming/javascript/typescript/conditional-types]]