Skip to main content

Literal Types

Flow has primitive types for literal values, but can also use literal values as types.

For example, instead of accepting number type, we could accept only the literal value 2.

1function acceptsTwo(value: 2) { /* ... */ }2
3acceptsTwo(2);   // Works!4
5acceptsTwo(3);   // Error!
6acceptsTwo("2"); // Error!
5:12-5:12: Cannot call `acceptsTwo` with `3` bound to `value` because number [1] is incompatible with number literal `2` [2]. [incompatible-call]
6:12-6:14: Cannot call `acceptsTwo` with `"2"` bound to `value` because string [1] is incompatible with number literal `2` [2]. [incompatible-call]

You can use primitive values for these types:

  • Booleans: like true or false
  • Numbers: like 42 or 3.14
  • Strings: like "foo" or "bar"
  • BigInts: like 42n

Using these with union types is powerful:

1function getColor(name: "success" | "warning" | "danger") {2  switch (name) {3    case "success" : return "green";4    case "warning" : return "yellow";5    case "danger"  : return "red";6  }7}8
9getColor("success"); // Works!10getColor("danger");  // Works!11
12getColor("error");   // Error!
12:10-12:16: Cannot call `getColor` with `"error"` bound to `name` because string [1] is incompatible with literal union [2]. [incompatible-call]

Consider using Flow Enums instead of unions of literal types, if they fit your use-case.