FrontendPrep
Menu
Topics
Questions
Guides
Challenges
Soon
Back to TypeScript Questions
typescriptEasy

TypeScript: Union and Intersection Types

Learn how union types (|) and intersection types (&) work in TypeScript. Understand how they combine primitive and object types, and how to narrow union types.

TypeScript: Union and Intersection Types

One of the common core questions in a TypeScript interview is:

Explain the differences between Union (|) and Intersection (&) types in TypeScript. How do they behave when applied to primitive types vs. object types?

Unions and intersections allow you to compose complex types out of simpler types. However, their behavior changes depending on whether they are combining primitives (like strings/numbers) or object types (interfaces).


1. Union Types (|)

A union type represents a value that can be one of several types. It is created using the pipe (|) symbol.

type ID = string | number;
 
let userId: ID;
userId = "abc"; // ✅ Allowed
userId = 123;   // ✅ Allowed
userId = true;  // ❌ Compile Error: Type 'boolean' is not assignable to type 'ID'.

Union behavior on Objects:

If you have a union of two object shapes, you can only safely access properties that are common to both types unless you perform type narrowing.

interface Bird {
  fly(): void;
  layEggs(): void;
}
interface Fish {
  swim(): void;
  layEggs(): void;
}
 
function getAnimal(): Bird | Fish { ... }
const pet = getAnimal();
 
pet.layEggs(); // ✅ Allowed (Common to both)
pet.swim();    // ❌ Compile Error (Only on Fish)

2. Intersection Types (&)

An intersection type combines multiple types into one type that has all the features of each. It is created using the ampersand (&) symbol.

interface Serializable {
  serialize(): string;
}
interface Loggable {
  log(): void;
}
 
type OutputModel = Serializable & Loggable;
 
const model: OutputModel = {
  serialize() { return "data"; },
  log() { console.log("Logged"); }
}; // ✅ Must implement both functions!

Intersection behavior on Primitives:

If you intersect two incompatible primitive types, you get never, because a value cannot be both a string and a number simultaneously:

type Impossible = string & number; // Type resolves to 'never'

3. Discriminated Unions

A common architectural pattern in TypeScript is the Discriminated Union (also called Tagged Unions). It is used to create clear, type-safe conditional logic by adding a common literal property (the "discriminant") to each member of the union.

interface SuccessResponse {
  status: "success"; // Discriminant
  data: string[];
}
 
interface ErrorResponse {
  status: "error"; // Discriminant
  message: string;
}
 
type ApiResponse = SuccessResponse | ErrorResponse;
 
function handleResponse(response: ApiResponse) {
  if (response.status === "success") {
    // TypeScript knows it is SuccessResponse here
    console.log(response.data);
  } else {
    // TypeScript knows it is ErrorResponse here
    console.log(response.message);
  }
}

Key Contrast Summary

| Behavior Feature | Union (|) | Intersection (&) | | :--- | :--- | :--- | | Logic Meaning | logical OR (either type A OR B) | logical AND (both type A AND B) | | Primitives | Creates a choice (string \| number) | Creates never (string & number) | | Object Properties | Only common properties are accessible | All properties of both types are accessible | | Common Use Case | Representing alternative states | Extending/combining object shapes |


Key Takeaways

  • Union Types: Created using | to allow a value to be one of several types, requiring narrowing to access non-common properties.
  • Intersection Types: Created using & to combine multiple types into a single type containing all members.
  • Primitive Intersection: Intersecting incompatible primitive types like string & number results in the never type.
  • Discriminated Unions: Leverage a literal discriminant property to perform clean, type-safe conditional logic.

Share this Resource

Help other developers level up by sharing this study guide.

More Technical Questions

Expand your mastery. Deep dive into other frontend interview challenges in this category.