0
0
Typescriptprogramming~15 mins

Extract type in Typescript - Deep Dive

Choose your learning style9 modes available
Overview - Extract type
What is it?
Extract type is a TypeScript utility type that creates a new type by selecting only those types from a union that are assignable to another type. It helps you filter a union type to keep only the parts you want. This is useful when you want to narrow down types for safer and clearer code.
Why it matters
Without Extract type, developers would have to manually write complex conditional types or repeat type checks, which can be error-prone and verbose. Extract type simplifies filtering types, making code easier to read, maintain, and less buggy. It helps prevent mistakes by ensuring only the correct types are used where expected.
Where it fits
Before learning Extract type, you should understand basic TypeScript types, union types, and type aliases. After mastering Extract type, you can explore other utility types like Exclude, ReturnType, and advanced conditional types to write more precise and reusable type definitions.
Mental Model
Core Idea
Extract type picks out only the parts of a union type that fit a specific condition, like a filter for types.
Think of it like...
Imagine you have a box full of different colored balls (types). Extract type is like a sieve that lets only the red balls (types matching a condition) pass through, separating them from the rest.
Union Type: A | B | C | D
Extract Condition: Keep only types assignable to B or D
Result: B | D

┌───────────────┐
│ A | B | C | D │  <-- Original union
└─────┬─┬───────┘
      │ │
      │ └── Keep D
      └──── Keep B

Filtered Result: B | D
Build-Up - 7 Steps
1
FoundationUnderstanding Union Types
🤔
Concept: Learn what union types are and how they combine multiple types into one.
In TypeScript, a union type means a value can be one of several types. For example, type Fruit = 'apple' | 'banana' | 'orange'; means a variable of type Fruit can be any of those three strings.
Result
You can assign 'apple' or 'banana' to a Fruit variable, but not 'carrot'.
Knowing union types is essential because Extract type works by filtering these unions.
2
FoundationBasic Type Filtering Concept
🤔
Concept: Understand the idea of selecting certain types from a group based on a condition.
Imagine you want only the string types from a union like string | number | boolean. Filtering means keeping only string and removing others.
Result
Filtered type would be just string.
This filtering idea is the foundation for how Extract type works.
3
IntermediateUsing Extract Type Syntax
🤔Before reading on: do you think Extract keeps types in T that are assignable to U, or those that are not? Commit to your answer.
Concept: Learn the syntax and basic usage of Extract type in TypeScript.
Extract takes two types: T (a union) and U (a condition). It returns a new type with only those types from T that can be assigned to U. Example: type T = string | number | boolean; type OnlyStrings = Extract; // OnlyStrings is string Here, Extract keeps only string from the union.
Result
OnlyStrings is just string, filtering out number and boolean.
Understanding the syntax lets you apply Extract type to narrow down unions easily.
4
IntermediateExtract with Custom Types
🤔Before reading on: if you Extract from a union of objects, do you think it matches by exact shape or by assignability? Commit to your answer.
Concept: Apply Extract type to complex types like object unions and interfaces.
Consider: interface Cat { kind: 'cat'; meow: () => void; } interface Dog { kind: 'dog'; bark: () => void; } type Pet = Cat | Dog; // Extract only Cats type OnlyCats = Extract; OnlyCats will be the Cat type because it matches the condition { kind: 'cat' }.
Result
OnlyCats is the Cat interface, filtering out Dog.
Extract uses assignability, so partial matches on object shapes work to filter unions.
5
IntermediateDifference Between Extract and Exclude
🤔Before reading on: do you think Extract and Exclude do the same thing or opposite? Commit to your answer.
Concept: Compare Extract with its opposite utility type Exclude to understand their complementary roles.
Extract keeps types from T assignable to U. Exclude removes types from T assignable to U. Example: type T = string | number | boolean; Extract // string | number Exclude // boolean
Result
Extract filters in; Exclude filters out.
Knowing both helps you choose the right tool to narrow or remove types from unions.
6
AdvancedExtract in Conditional Types
🤔Before reading on: do you think Extract can be used inside conditional types to create dynamic filters? Commit to your answer.
Concept: Use Extract inside conditional types to build flexible, reusable type logic.
Conditional types let you write types that change based on input. Example: type FilterString = Extract; FilterString // string You can combine Extract with other conditional logic to create powerful type transformations.
Result
Extract helps build dynamic type filters that adapt to input types.
Understanding this unlocks advanced type programming and safer APIs.
7
ExpertExtract Type Internals and Edge Cases
🤔Before reading on: do you think Extract always returns a subtype of the original union, or can it sometimes produce never? Commit to your answer.
Concept: Explore how Extract works internally and what happens with no matches or complex unions.
Extract is implemented as a conditional type: T extends U ? T : never This means each member of T is tested against U. If none match, the result is never. Example: Extract // never Also, Extract distributes over unions, so it tests each member separately. Edge cases include: - Extracting with never returns never - Extracting with any returns the original union - Complex nested unions can produce unexpected results if not carefully designed.
Result
Extract returns a filtered union or never if no types match.
Knowing the internal conditional type helps predict behavior and avoid subtle bugs.
Under the Hood
Extract type uses TypeScript's conditional types feature. It checks each member of the union type T to see if it can be assigned to type U. If yes, it keeps that member; if not, it replaces it with never. Then TypeScript combines all kept members into a new union type. This process is called distributive conditional types because the condition applies separately to each union member.
Why designed this way?
TypeScript designed Extract as a distributive conditional type to allow precise filtering of union types without extra syntax. This design leverages existing conditional types and union distribution, making Extract simple, composable, and efficient. Alternatives like manual filtering would be verbose and error-prone, so this approach balances power and simplicity.
Extract<T, U> Mechanism:

┌─────────────┐
│   Union T   │
│ A | B | C   │
└─────┬───────┘
      │
      ▼ (Check each member if assignable to U)
┌─────────────┐
│ Conditional │
│  T extends U│
│   ? T : never│
└─────┬───────┘
      │
      ▼
┌─────────────┐
│ Filtered    │
│ Union       │
│ B | C       │
└─────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does Extract keep types in T that are NOT assignable to U? Commit yes or no.
Common Belief:Extract keeps types that are not assignable to U.
Tap to reveal reality
Reality:Extract keeps only types from T that are assignable to U, filtering out the rest.
Why it matters:Misunderstanding this leads to wrong type filtering, causing type errors or unexpected behavior.
Quick: If Extract finds no matching types, does it return T or never? Commit your answer.
Common Belief:Extract returns the original type T even if no matches exist.
Tap to reveal reality
Reality:Extract returns never if no types in T match U.
Why it matters:Assuming Extract always returns something can cause bugs when the result is never, which means no valid type.
Quick: Does Extract work by exact type equality or assignability? Commit your answer.
Common Belief:Extract matches types by exact equality only.
Tap to reveal reality
Reality:Extract uses assignability, so types that can be assigned to U are kept, even if not exactly equal.
Why it matters:This affects how object types and interfaces are filtered, which can surprise developers expecting exact matches.
Quick: Can Extract be used to filter types inside nested unions automatically? Commit yes or no.
Common Belief:Extract automatically filters nested unions deeply.
Tap to reveal reality
Reality:Extract only distributes over the top-level union; nested unions inside members are not filtered automatically.
Why it matters:Expecting deep filtering can cause incorrect assumptions about the resulting type shape.
Expert Zone
1
Extract distributes over unions, meaning it applies the condition to each member separately, which can lead to unexpected results if the union members are complex types.
2
Extract uses assignability, not exact equality, so it can keep types that are subtypes or compatible with the condition type, which is subtle but powerful.
3
When Extract returns never, it signals no matches, which can be used intentionally in advanced type logic to detect impossible cases.
When NOT to use
Avoid Extract when you need to remove types instead of keeping them; use Exclude instead. Also, do not use Extract for deep nested filtering inside complex types; consider recursive conditional types or mapped types for that. If you need exact type matches rather than assignability, Extract may not be precise enough.
Production Patterns
Extract is commonly used in libraries to create safer APIs by narrowing union types based on input parameters. For example, filtering event types, action types in Redux, or discriminated unions in state machines. It is also used in generic utility types to build flexible, reusable type transformations.
Connections
Set Theory
Extract acts like the intersection operation between two sets of types.
Understanding Extract as set intersection helps grasp how it filters types that belong to both sets, making type operations intuitive.
Database Query Filtering
Extract is similar to filtering rows in a database table based on a condition.
Seeing Extract as a filter operation on data helps relate type filtering to everyday data handling tasks.
Biology - Natural Selection
Extract resembles natural selection by keeping only types that 'fit' a condition, like organisms fit for an environment.
This connection shows how selection processes in nature and programming share the idea of filtering for suitability.
Common Pitfalls
#1Expecting Extract to filter nested union types automatically.
Wrong approach:type Nested = Extract<'a' | ('b' | 'c'), 'b'>; // expects 'b' only
Correct approach:type Nested = 'a' | Extract<'b' | 'c', 'b'>; // manually extract nested union
Root cause:Extract only distributes over the top-level union, not nested unions inside members.
#2Using Extract when you want to remove types instead of keep them.
Wrong approach:type T = string | number; type Result = Extract; // keeps number, but wanted to remove it
Correct approach:type Result = Exclude; // removes number, keeps string
Root cause:Confusing Extract (keep) with Exclude (remove) leads to wrong type results.
#3Assuming Extract matches types by exact equality.
Wrong approach:type T = { a: number } | { b: string }; type Result = Extract; // expects only exact matches
Correct approach:type Result = Extract; // keeps types assignable to { a: number }
Root cause:Extract uses assignability, so partial matches count, which can surprise learners expecting exact matches.
Key Takeaways
Extract type filters a union type by keeping only members assignable to a given type, acting like a type-level filter.
It works by distributing a conditional type over each member of the union, returning a new union of matching types or never if none match.
Extract uses assignability, not exact equality, so it can keep subtypes or compatible types, which is important to understand for object types.
Extract is complementary to Exclude, which removes types instead of keeping them, and both are essential tools for precise type manipulation.
Knowing Extract deeply helps write safer, clearer, and more reusable TypeScript code by narrowing types effectively.