Skip to main content
An intersection type combines multiple types into a single type that enforces the constraints of all constituent types simultaneously. Denoted by the ampersand (&) operator, a value of an intersection type must satisfy all type signatures defined across the intersected types.

Object Type Merging

When intersecting object types, the resulting type contains the union of all property keys from the constituent types. TypeScript preserves the intersection structure lazily (e.g., representing it as Identifiable & Auditable in the compiler). For non-overlapping properties, the original optionality modifiers are strictly maintained; if a unique property is optional in its constituent type, it remains optional in the intersection.

Overlapping Properties and Optionality

If constituent types share a property key, the type of that shared property in the resulting intersection becomes the intersection of the overlapping types. The compiler maintains this representation without eagerly flattening nested structures.
When overlapping properties have differing optionality modifiers, the required modifier strictly overrides the optional modifier. If a property is optional in one constituent type but required in another, the property becomes strictly required in the resulting intersection type.

Mutually Exclusive Types and never

Intersecting mutually exclusive types (such as disjoint primitives) yields the bottom type, never, because no runtime value can simultaneously satisfy both constraints.
When intersecting object types with overlapping properties of mutually exclusive non-unit types (such as string and number), the specific property evaluates to never, but the object type itself remains intact.
However, since TypeScript 3.9, if the conflicting properties are discriminant properties—specifically unit types such as literal types, true/false, null, or undefined—the compiler eagerly reduces the entire intersection type to never.

Function Intersections

Intersecting multiple function signatures creates an overloaded function type. A function assigned to this intersection must be callable with any of the intersected signatures, effectively combining the parameter lists as overloads.

Interaction with Top and Bottom Types

Intersection types have specific behaviors when evaluated against TypeScript’s top types (any and unknown) and the bottom type (never):
  • any: Intersecting any type T with any yields any, with the strict exception of never. The intersection any & never evaluates to never because the bottom type represents an empty set and overrides any in intersections.
  • unknown: Intersecting any type T with unknown acts as an identity operation, yielding T. Because unknown is the universal supertype, it imposes no additional constraints on T.

Distributivity over Unions

Intersection distributes over union types. When an intersection operation involves a union, the TypeScript compiler applies the intersection to each member of the union individually, simplifying never types out of the final result.
Tired of Poor TypeScript Skills? Fix That With Deep Grasping!Learn More