Union
The pipe (|
) in a union can be properly thought of as "or", since it means that "this variable can be of one type or the other"
A Union is a way to achieve type composition (as are intersections)
- composition being a way to create new types from existing types
The rule for union types is that we only allow an operation if it would be legal to do on each member of the union
For example, with the given code:
type Props = {
items: ClientNugget[] | ClientBucket[]
onPressHandler?: (item: ClientNugget | ClientBucket) => void
}
That means onPressHandler
must be able to accept both types: ClientNugget and ClientBucket. This is not the same as saying "this function will accept one of these types at runtime." TypeScript needs to know that whatever function is passed in will be able to handle either one — even if only one will be used at runtime depending on the context.
If we wrote this code:
const handleSelectBucket = (bucket: ClientBucket) => { ... }
<ChipContainer items={buckets} onPressHandler={handleSelectBucket} />
This function only accepts a ClientBucket, which is not compatible with (item: ClientNugget | ClientBucket) => void. Why?
Because from the type system’s perspective, if the function could be called with a ClientNugget, it would fail. That’s why it complains — you're trying to assign a function that only accepts a narrower type (ClientBucket) to a prop expecting a broader type (ClientNugget | ClientBucket).
let ambiguouslyEmptyAlice: Person | null | undefined;
Take the following union:
interface Foo {
foo: string;
xyz: string;
}
interface Bar {
bar: string;
xyz: string;
}
const sayHello = (obj: Foo | Bar) => { /* ... */ };
Here, we are saying "Foo | Bar
is a type that has either all required properties of Foo
OR all required properties of Bar
."
- In the absence of a guard, we'd only be able to access
obj.xyz
, since that is the only property that exists on either type.
Union type is very often used with either null or undefined.
const sayHello = (name: string | undefined) => { /* ... */ };
Relation to Unions in statistics
When we consider unions (Private) in a statistical sense, it may seem counter-intuitive how Unions and Intersections are implemented in Typescript.
- If have have a union type
string | number
, it means the type has to be either string or number. - If we have an intersection type, it means the type must have both.
The lack of clarity lies in the perspective we are taking. We are meant to take the perspective of what is accepted as the union type.
- we say that the set of things that can be set to
string | number
is the union of the string set and the number set.- ex. imagine there was a big list of all strings and all numbers that were loaded into memory. The union of
string | number
would be the set of all of them
- ex. imagine there was a big list of all strings and all numbers that were loaded into memory. The union of
- we say that the set of things that can be set to
string & number
is zero, because there is zero overlap betweenstring & number
.
Put another way, the incorrect way to see it is: "a union is a set operator on the field". The correct way is "a union is a set operator of the sets of what each type represents."
Children
Backlinks