Intersection Syntax
Intersection types in TypeScript combine multiple types into one using the & operator. Unlike union types (which allow either type), intersection types require all types to be present simultaneously. The basic syntax is Type1 & Type2. This creates a new type that has all properties from both Type1 and Type2. If Type1 has property A and Type2 has property B, the intersection type has both A and B.
You can combine more than two types: Type1 & Type2 & Type3. The order doesn't matter because intersection is commutative: A & B is the same as B & A. Intersection types work with primitives, though combining primitive types creates unusual types. For example, string & number creates a type that is simultaneously a string and a number, which is impossible at runtime. This type is called 'never' because no value can satisfy it. More commonly, intersections combine object types, interfaces, or type aliases.
The resulting type has all properties from all intersected types. When properties have the same name, their types must be compatible (i.e., one must be a subtype of the other). If they're incompatible, TypeScript raises an error. For example, if Type A has {x: string} and Type B has {x: number}, then A & B is an error because x cannot be both string and number. However, if Type A has {x: string} and Type B has {x: 'hello'}, then A & B is valid because 'hello' is a subtype of string.
Intersection types can also be used with literal types to create more specific types. For example, you can combine a string type with a literal type to create a type that must be a specific string value. This is useful for creating exhaustive type checks. Intersection types are evaluated lazily, meaning the compiler only resolves them when needed. This improves performance in large codebases with many complex type combinations. The & operator has lower precedence than most other type operators, so you may need parentheses in complex expressions: (A | B) & C.
Combining Types
You can use intersection types to combine interfaces, creating more specific types. This is similar to interface extension but more flexible since it works with type aliases too. When combining interfaces, properties with the same name must be compatible (same type or one is subtype). With generics, intersection types can create powerful abstractions. For example, you can create a generic function that takes a base type and extends it with additional properties using intersection.
Intersection types also work with mapped types and conditional types for advanced type manipulation. You can intersect a mapped type with another type to add or modify properties. Conditional types can distribute over unions, and intersection can be used to narrow types in complex scenarios. This flexibility makes them essential for complex type scenarios.
A common pattern is using intersection to add metadata to existing types. For instance, you can have a base User type and intersect it with Timestamps type to create UserWithTimestamps. This avoids modifying the original User type, following the open/closed principle. Another pattern is creating mixin types by intersecting multiple function types or object types. Mixins allow you to compose behaviors from multiple sources without traditional inheritance.
Intersection types also enable creating strict API response types. You can intersect a base response type with specific data shapes to ensure type safety across your API layer. When combined with type guards, intersection types help create exhaustive checks that ensure all possible types are handled. This pattern is particularly useful in state management where actions must be exhaustive. For example, you can intersect action types with payload types to create precise action definitions that prevent invalid actions.
Another powerful pattern is using intersection types with utility types. You can intersect Partial
Use Cases
Intersection types have several practical applications in real-world TypeScript codebases. In React, they're used to combine component props with additional properties. For example, you might have a ButtonProps interface and intersect it with AdditionalProps to create ExtendedButtonProps. This allows component composition without modifying original prop types. You can also intersect props with route props for page components that need access to route parameters.
For API responses, you can combine a base response type with specific data shapes. This is useful when you have multiple API endpoints that share common fields but differ in their data payloads. Intersection types let you define each endpoint's type precisely while reusing common response structure. You can intersect a BaseResponse type with UserDataType or ProductDataType depending on the endpoint.
Mixins in object-oriented design can be implemented using intersection types. A mixin is a class that provides methods that can be used by other classes. By intersecting a base class type with mixin types, you can create classes that have multiple inheritance-like behavior without the complexity of class inheritance. This pattern is common in libraries that provide composable behaviors.
They're also useful for adding metadata to existing types without modifying the original type definition. When working with third-party libraries, intersection types let you extend existing types with custom properties. This is safer than declaration merging because it doesn't affect other code using the original type. You can create wrapper types that add validation, logging, or other cross-cutting concerns.
Another common use is creating discriminant unions with shared properties. By intersecting a discriminant property type with union types, you can ensure type safety while maintaining flexibility. Intersection types also help in creating factory functions that return different types based on input, while maintaining type safety through conditional types and intersections. In form handling, intersection types can combine form field types with validation rules, ensuring each field has both its value type and validation constraints. For state management, intersection types can combine action types with payload types, creating precise action definitions that prevent invalid actions.
Practice Problems
Create a reusable React component implementing Intersection Types. Include proper state management and accessibility.
Solution
// Production-ready component with:
// - Proper TypeScript types
// - Accessibility (ARIA)
// - Error boundaries
// - Loading states
// - Memoization where neededWrite unit and integration tests for Intersection Types using React Testing Library.
Solution
// Test coverage:
// 1. Rendering tests
// 2. Interaction tests
// 3. Edge case tests
// 4. Accessibility testsOptimize Intersection Types for performance. Consider memoization, code splitting, and bundle size.
Solution
// Optimization techniques:
// 1. React.memo / useMemo / useCallback
// 2. Code splitting with lazy()
// 3. Virtual scrolling for lists
// 4. Image lazy loading
// 5. Bundle analysisQuiz
1. What does the & operator create in TypeScript?
2. If Type A has {x: number} and Type B has {y: string}, what does A & B have?
3. How does intersection differ from union types?
4. What is the primary purpose of Intersection Types?
Flashcards
Question
What operator creates intersection types?
Click to reveal answer
Answer
The & (ampersand) operator.
Question
What's the difference between intersection and union types?
Click to reveal answer
Answer
Intersection requires all types simultaneously, union requires any one type.
Question
Name a practical use case for intersection types.
Click to reveal answer
Answer
Combining React component props with additional properties.
Question
What is Intersection Types?
Click to reveal answer
Answer
Intersection Types is a key concept in frontend development.
Question
When to use Intersection Types?
Click to reveal answer
Answer
Use Intersection Types when building production systems that require reliability, scalability, and maintainability.
Revision Notes
Key Takeaways
- 1.Intersection types combine multiple types using &
- 2.Resulting type has all properties from all intersected types
- 3.More flexible than interface extension for type aliases
- 4.Useful for extending third-party types
- 5.Common in React props and API response types
Interview Tips
- •Explain intersection vs union types clearly
- •Show examples of combining interfaces
- •Discuss real-world use cases like React props
- •Mention limitations with primitive intersections
Cheat Sheet
Intersection types: combine multiple types with &; require all properties; work with interfaces and type aliases; used for extending types without modification