# Appendix: Subtyping rules

Each value in FlowScript belongs to at least one type. The value **true**, for example, belongs to the type **boolean**, and the value `{x: 1}` belongs to type `{x: number}`. The types themselves have mutual relationships. This document outlines the relationship between the types in FlowScript

## Subtypes and supertypes

You may think of a type as a set of values. The type **boolean** is the set containg the two values **true** and **false**. The type **boolean?** (nullable boolean) is the set containing the three values **true**, **false** and **null.**

Because all members of the **boolean** set are also members of the **boolean?** set, **boolean** is a *subtype* of **boolean?**.

{% hint style="info" %}
If **A** is a subtype of **B**, it means that you may pass values of type **A** whenever a value of type **B** is called for.

If **A** is a *subtype* of **B**, we say that **B** is a *supertype* of **A**.
{% endhint %}

```typescript
// Example 1: we can assign a value of type boolean
// to a variable of type boolean?.
// In other words, boolean is a subtype of boolean?.

let x: boolean = false;
let y: boolean? = x; // no problem
```

```typescript
// Example 2: we cannot assign any value of type boolean?
// to a variable of type boolean.
// In other words, boolean? is not a subtype of boolean.

let x: boolean? = null;
let y: boolean = x; // Type mismatch
```

## Record subtyping

FlowScript record values are subject to *width and depth subtyping* rules. Width subtyping means that a record `{x: number, y: number}` is a subtype `{x: number}`. Depth subtyping means that a record `{x: boolean}` is a subtype of `{x: boolean?}`.&#x20;

Intuitively, we can think of a record type as specifying the *minimum* members that a record must have. A record is allowed to have more members than required, but not less.

```typescript
// Example: demonstrate width subtyping of records
let user = {id: 1, name: "Leon"};

// We can update the "user" variable with a record containing
// more fields than required by its type.
set user = {id: 2, name: "Theodora", email: "theodora@example.com"};
```

In the example above, the user variable after the **set** statement has an extra member called email. The *type* of the variable, however, does not include the email member, so we cannot access it directly. The member is still there, but you must use type narrowing to "find" it.

## Lowest common supertype

For any pair of types **A** and **B**, there exists at least one type **C** which is a supertype of **A** and **B**. The type **unknown** is supertype of all other types, but sometimes there is a more useful and specific common supertype. This is known as the lowest common supertype (LCS).

For example, given the types `{name: text, email: text}` and `{name: text, age: number}`, the lowest common supertype is `{name: text}`. We can think of the LCS as the "common denominator" of two types.

```typescript
// Example of a situation where FlowScript will
// find the lowest common supertype of several values.

let people = [
    {name: "Gregorsz", email: "gregorsz@example.com"},
    {name: "Felicia", age: 51}
];
```

Similarly, the LCS of **boolean** and **boolean?** is **boolean?** and the LCS of **number\*** and **text\*** is **text\***.
