Real World Example

Handling Ride Events

A ride-hailing app like Uber or Ola receives a stream of events from drivers. Each event type carries different data. A discriminated union plus an exhaustive switch keeps the event handler correct as new events are added.

Example

type RideEvent =
  | { type: "REQUESTED"; rideId: string; pickup: string }
  | { type: "ACCEPTED"; rideId: string; driver: string; etaMin: number }
  | { type: "STARTED"; rideId: string }
  | { type: "COMPLETED"; rideId: string; fare: number; km: number }
  | { type: "CANCELLED"; rideId: string; by: "rider" | "driver"; fee?: number };

function assertNever(x: never): never { throw new Error("Unknown event " + JSON.stringify(x)); }

function notify(e: RideEvent): string {
  switch (e.type) {
    case "REQUESTED": return `Finding a driver near ${e.pickup}...`;
    case "ACCEPTED": return `${e.driver} arrives in ${e.etaMin} min`;
    case "STARTED": return "Ride started. Have a safe trip!";
    case "COMPLETED": return `Trip of ${e.km} km done. Fare Rs. ${e.fare}`;
    case "CANCELLED":
      return `Cancelled by ${e.by}` + (e.fee ? `, fee Rs. ${e.fee}` : "");
    default: return assertNever(e);
  }
}

const events: RideEvent[] = [
  { type: "REQUESTED", rideId: "R1", pickup: "HITEC City" },
  { type: "ACCEPTED", rideId: "R1", driver: "Suresh", etaMin: 4 },
  { type: "STARTED", rideId: "R1" },
  { type: "COMPLETED", rideId: "R1", fare: 286, km: 11.4 },
  { type: "CANCELLED", rideId: "R2", by: "rider", fee: 50 },
];
events.forEach((e) => console.log(e.rideId, "|", notify(e)));

Output

R1 | Finding a driver near HITEC City...
R1 | Suresh arrives in 4 min
R1 | Ride started. Have a safe trip!
R1 | Trip of 11.4 km done. Fare Rs. 286
R2 | Cancelled by rider, fee Rs. 50