A good first step while building a new application is to define its domain model. TypeScript offers many tools to help you in this task. Algebraic Data Types (ADT for short) are one of these tools.

What is an ADT?

In computer programming, especially functional programming and type theory, an algebraic data type is a kind of composite type, i.e., a type formed by combining other types.

Two common classes of algebraic types are:

Product types

A product type is a collection of types Ti indexed by a set I.

Two common members of this family are n-tuples, where I is a non empty interval of natural numbers...

type Tuple1 = [string] // I = [0]
type Tuple2 = [string, number] // I = [0, 1]
type Tuple3 = [string, number, boolean] // I = [0, 1, 2]

// Accessing by index
type Fst = Tuple2[0] // string
type Snd = Tuple2[1] // number

...and structs, where I is a set of labels.

// I = {"name", "age"}
interface Person {
  name: string
  age: number
}

// Accessing by label
type Name = Person['name'] // string
type Age = Person['age'] // number

Why "product" types?

If we write C(A) for the number of inhabitants of the type A (aka its cardinality) then the following equality holds

C([A, B]) = C(A) * C(B)

the cardinality of the product is the product of cardinalities

Example

type Hour = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12
type Period = 'AM' | 'PM'
type Clock = [Hour, Period]

The Clock type has 12 * 2 = 24 inhabitants.