Typescript: Intersection - Confused about the naming
Asked Answered
I

1

9

I am a bit confused about the name Intersection Types in Typescript.

In set theory, intersection would imply that only properties that are common to both types would be available in the intersection of the two.

In fact, that is how Typescript behaves if I create an intersection between primitives.

type A = string | number
type B = number | boolean
type C = A & B

type D = string
type E = number
type F = D & B

In this case, TS infers C to be number, and F to be never.

enter image description hereenter image description here

However, when it comes to objects, creating an intersection creates a new type/interface that combines the properties of the used types -

enter image description hereenter image description here

From the documentation

TypeScript provides another construct called intersection types that is mainly used to combine existing object types

The behavior for objects makes perfect sense when you look at this way. And using & also makes sense.

So, my questions are these:

  1. Why does the behavior seem different for objects and primitives?
  2. Why was the name intersection chosen ?

Maybe it is somehow related to this explanation with Union types ?

enter image description here

Isopod answered 23/1, 2022 at 5:48 Comment(1)
Aren’t objects row types? That is, if something is an ObA, that means it has a name and an onlyA (among possibly other attributes) and so on for ObB. That means that if something is both an ObA and an ObB, it must have a name, an onlyA, and an onlyB. Primitives don’t work the same way because they’re not row types — an integer is just an integer, it can’t be an integer and also something with a name.Lated
S
9

An intersection between two sets would yield elements that are in both sets.

Types are just descriptions of sets of values.

So for the intersection of primitives string & number, what value is in both the string set and the number set, ie. can be both a string and number at the same time. The answer is there is no such value. So we get never (the empty set)

For object types the result is a bit different. Object types describe sets where the value must have at least the properties described by the type. So values in the set { name: string, onlyA: string[] } could have a property onlyB, but they are not required to have it (ex).

Going back to the intersection ObA & ObB, values in this intersection must satisfy both the description of ObA and ObB. So the values in this set will be the values from ObA that also have an onlyB property, and the values from ObB that also have an onlyA property. Basically values that satisfy both set descriptions, which for object types unlike for primitives we can construct by creating objects with properties from both types.

My tsconf workshop starts with a "Types as sets" section you might find interesting.

Solothurn answered 23/1, 2022 at 7:34 Comment(4)
This makes it clear: > values in this intersection must satisfy both the description of ObA and ObBIsopod
However, i'm not sure if this is true: Object types describe sets where the value must have at least the properties described by the type. So values in the set { name: string, onlyA: string[] } could have a property onlyB, but they are not required to have it. if i try to add onlyB to an object of type obA, TS gives me an error. typescriptlang.org/play?#code/…Isopod
@Eels That is called excess property checks and only happens in a very special case, when you assign an object literal to a typed variable. It's there to prevent common errors, but it does go against normal subtyping rules. If you go thought an extra an extra variable, then this error no longer occurs (as i show in the example)Solothurn
So okay "So the values in this set will be the values from ObA that also have an onlyB property, and the values from ObB that also have an onlyA property", It's an exact definition of Union. So I would say that for type primitives Intersection does work, but for object types A| B => OR A OR B , A & B => union of the fields in the single objectBattlefield

© 2022 - 2024 — McMap. All rights reserved.