Utility Types

Utility Types#

$Keys<T>#

In Flow you can use union types similar to enums:

1
2
3
4
type Suit = "Diamonds" | "Clubs" | "Hearts" | "Spades";

const clubs: Suit = 'Clubs';
const wrong: Suit = 'wrong'; // 'wrong' is not a Suit
show Flow output hide Flow output
$> flow
4: const wrong: Suit = 'wrong'; // 'wrong' is not a Suit
                       ^^^^^^^ string. This type is incompatible with
4: const wrong: Suit = 'wrong'; // 'wrong' is not a Suit
                ^^^^ string enum

This is very handy, but sometimes you need to access the enum definition at runtime (i.e. at a value level).

Suppose for example that you want to associate a value to each suit of the previous example.

You could do

1
2
3
4
5
6
7
8
9
10
11
12
13
const suitNumbers = {
  Diamonds: 1,
  Clubs: 2,
  Hearts: 3,
  Spades: 4
};

function printSuitNumber(suit: Suit) {
  console.log(suitNumbers[suit]);
}

printSuitNumber('Diamonds'); // 2
printSuitNumber('foo'); // 'foo' is not a Suit
show Flow output hide Flow output
$> flow
13: printSuitNumber('foo'); // 'foo' is not a Suit
                    ^^^^^ string. This type is incompatible with the expected param type of
8: function printSuitNumber(suit: Suit) {
                                  ^^^^ string enum

but this doesn’t feel very DRY, as we had to explicitly define the suit names twice.

In situations like this one, you can leverage the $Keys<T> operator. Let’s see another example, this time using $Keys:

1
2
3
4
5
6
7
8
9
10
const countries = {
  US: "United States",
  IT: "Italy",
  FR: "France"
};

type Country = $Keys<typeof countries>;

const italy: Country = 'IT';
const nope: Country = 'nope'; // 'nope' is not a Country
show Flow output hide Flow output
$> flow
10: const nope: Country = 'nope'; // 'nope' is not a Country
                          ^^^^^^ property `nope`. Property not found in
10: const nope: Country = 'nope'; // 'nope' is not a Country
                ^^^^^^^ object literal

In the example above, the type of Country is equivalent to type Country = 'US' | 'IT' | 'FR', but Flow was able to extract it from the keys of countries.

$Diff<A, B>#

As the name hints, $Diff<A, B> is the type representing the set difference of A and B, i.e. A \ B, where A and B are both Object Types. Here’s an example:

1
2
3
4
5
6
7
8
9
10
11
type Props = { name: string, age: number };
type DefaultProps = { age: number };
type RequiredProps = $Diff<Props, DefaultProps>;

function setProps(props: RequiredProps) {
  // ...
}

setProps({ name: 'foo' });
setProps({ name: 'foo', age: 42, baz: false }); // you can pass extra props too
setProps({ age: 42 }); // error, name is required
show Flow output hide Flow output
$> flow
11: setProps({ age: 42 }); // error, name is required
    ^^^^^^^^^^^^^^^^^^^^^ function call
5: function setProps(props: RequiredProps) {
                            ^^^^^^^^^^^^^ property `name`. Property not found in
11: setProps({ age: 42 }); // error, name is required
             ^^^^^^^^^^^ object literal

As you may have noticed, the example is not a random one. $Diff is exactly what the React definition file uses to define the type of the props accepted by a React Component.

Class<T>#

Work in progress

$Supertype<T>#

Work in progress

$Subtype<T>#

Work in progress

$Abstract<T>#

Work in progress

#PropertyType<T, x>#

Work in progress

← Prev Next →

You can edit this page on GitHub and send us a pull request!