Discriminated Unions

Discriminated Unions (or tagged union types) are a form of type guards where the type is narrowed based on a shared property.

In the following example, the type of Dog and Person have a shared property called type. Depending on the value of this property, TypeScript can narrow down the type from Dog | Person to either Dog or Person:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
type Dog = {
age: number;
name: string;
bark: () => void;
type: 'dog'
}

type Person = {
age: number;
name: string;
shout: () => void;
type: 'person'
}

function makeNoise(dogOrPerson: Dog | Person): void {
switch (dogOrPerson.type) {
case 'dog':
// Type is narrowed down to "Dog", so we can "bark":
dogOrPerson.bark();
break;
case 'person':
// Type is narrowed down to "Person", so we can "shout":
dogOrPerson.shout();
break;
}
}

Because this allows the type to be discriminated, this technique is referred to as discriminating unions. This concept also exists in F# (Discriminated Unions in F#).