Suggest an editImprove this articleRefine the answer for “What does Exclude<T, U> do?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**`Exclude<T, U>`** is a utility type that creates a new union by removing from `T` every member assignable to `U`; it is implemented as `T extends U ? never : T`. **Key point:** if `U` does not overlap with `T`, the result is unchanged, and unlike `Omit`, `Exclude` operates on union members rather than object keys.Shown above the full answer for quick recall.Answer (EN)Image## 1. What `Exclude<T, U>` does > `Exclude<T, U>` creates a **new type** > by excluding from `T` all types that are **assignable to** `U`. In simpler terms, it *"subtracts"* one union from another. --- ### Example ```javascript type Letters = 'a' | 'b' | 'c'; type WithoutB = Exclude<Letters, 'b'>; // => 'a' | 'c' ``` > The type `'b'` is excluded, while `'a'` and `'c'` remain. --- ## 2. How `Exclude` works with union types When `T` is a union, TypeScript **goes through every member** of `T` and **removes** the ones assignable to `U`. --- ### Example 1 ```javascript type T = 'a' | 'b' | 'c'; type U = 'a' | 'c'; type Result = Exclude<T, U>; // 'b' ``` > `'a'` and `'c'` were in `U`, so they are excluded. > `'b'` remains. --- ### Example 2 ```javascript type Primitive = string | number | boolean; type NoStrings = Exclude<Primitive, string>; // number | boolean ``` > `string` is excluded, the other types are kept. --- ## 3. What happens if `U` is not part of `T` If `U` does not overlap with `T`, then **nothing is removed**, and the result is simply `T`. --- ### Example ```javascript type T = 'a' | 'b'; type U = 'x' | 'y'; type Result = Exclude<T, U>; // 'a' | 'b' (unchanged) ``` > TypeScript "tries to subtract", but finds no matches, > so `Exclude` changes nothing. --- ## 4. How `Exclude` is implemented internally Here is what its real implementation in TypeScript looks like: ```javascript type Exclude<T, U> = T extends U ? never : T; ``` Explanation: - Every member of `T` is checked individually: if it is assignable to `U`, it is replaced with `never` (excluded); - the rest are kept. --- ## 5. Example with `never` ```javascript type T = 'a' | 'b'; type U = 'a'; type Result = Exclude<T, U>; // 'b' // essentially this works like: type Result = ('a' extends 'a' ? never : 'a') | ('b' extends 'a' ? never : 'b'); // => never | 'b' → 'b' ``` --- ## 6. The difference between `Exclude` and `Omit` These types are **similar in meaning ("remove something")**, but they work **in different contexts**. | Comparison | `Exclude<T, U>` | `Omit<T, K>` | |---|---|---| | Works with | union types | objects (interfaces) | | Removes | types (values from the union) | properties (keys) | | Input example | `'a' | 'b' | | Removal example | `Exclude<'a' | 'b' | | Based on | conditional types (`extends`) | a combination of `Pick` + `Exclude` | --- ### Example of the difference in practice ```javascript // Exclude type Letters = 'a' | 'b' | 'c'; type Result1 = Exclude<Letters, 'b'>; // 'a' | 'c' // Omit interface User { id: number; name: string; email: string; } type Result2 = Omit<User, 'email'>; // { id: number; name: string } ``` > `Exclude` works at the level of **value types**, > `Omit` works at the level of **object keys**. --- ## 7. Combining with other utilities ### Example: excluding part of a union field of an interface ```javascript interface ApiResponse { status: 'success' | 'error' | 'loading'; data: string; } type NoLoading = Exclude<ApiResponse['status'], 'loading'>; // 'success' | 'error' ``` --- ### Example: creating a type "without null and undefined" ```javascript type Clean<T> = Exclude<T, null | undefined>; type Value = Clean<string | null | undefined>; // string ``` --- ## Summary | Question | Answer | |---|---| | What does `Exclude<T, U>` do | Removes from `T` all types assignable to `U` | | How it works with union types | Checks every member and excludes the matching ones | | What if `U` is not part of `T` | The result stays the same (`T` does not change) | | How it differs from `Omit` | `Exclude` works with a *union*, while `Omit` works with *object keys* |For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.