TypeScript Intersection Types Done Right: When They Compose Cleanly and When They Silently Lie
This article was written with the assistance of AI, under human supervision and review.
Most TypeScript composition failures stem from developers treating intersection types as simple object merging. The pattern teams overlook is that intersections follow set-theoretic rules, not object-spread semantics. When developers write A & B, they expect "all properties from A plus all properties from B." What they get is "values that satisfy both A and B simultaneously." This distinction is critical because it determines when composition produces useful types and when it silently creates never, breaking type safety without warning.
The failure mode here is subtle but expensive. A developer combines two types expecting a richer interface. The compiler accepts it. Tests pass. Then production breaks because the intersection resolved to never, accepting literally any value. The fix requires understanding when intersection types compose cleanly versus when they conflict, and knowing which composition tool to reach for in each scenario.
Problem flow showing how naive intersection creates never type






