2 min read

TypeScript Intersection Types

Intersection types allow you to combine multiple types into one. This creates a new type that has all the features of the combined types.

1. Syntax

You use the ampersand & operator to create an intersection.

type Combined = TypeA & TypeB;

An object of type Combined must satisfy both TypeA and TypeB.

2. Combining Interfaces/Objects

This is the most common use case: merging two object shapes.

interface ErrorHandling {
  success: boolean;
  error?: { message: string };
}

interface ArtworksData {
  artworks: { title: string }[];
}

type ArtworksResponse = ArtworksData & ErrorHandling;

const handleArtistsResponse = (response: ArtworksResponse) => {
  if (response.error) {
    console.error(response.error.message);
    return;
  }

  console.log(response.artworks);
};

3. Intersection vs Union

  • Union (|): The value can be either Type A or Type B. You can only access members common to both unless you narrow the type.
  • Intersection (&): The value is both Type A and Type B. You can access members from both.

4. Type Conflicts

If you intersect types that have the same property key but incompatible types, that property becomes never.

type A = { id: number };
type B = { id: string };

type C = A & B; 
// C is { id: number & string } -> { id: never }
// No value can be both a number and a string at the same time.

5. Use Case: Mixins and Composition

Intersection types are great for functional composition or mixin patterns where you add capabilities to an object.

function extend<T, U>(first: T, second: U): T & U {
  return { ...first, ...second };
}

const x = extend({ a: "hello" }, { b: 42 });

// x has both properties
console.log(x.a); // string
console.log(x.b); // number

programming/javascript/typescript/typescript