Types
Primitives
Section titled “Primitives”const name: string = "Alice"const age: number = 30const active: boolean = trueRecord Types
Section titled “Record Types”type User { name: string, email: string, age: number,}Construct records with the type name:
const user = User(name: "Alice", email: "a@b.com", age: 30)Update with spread:
const updated = User(..user, age: 31)Record Type Composition
Section titled “Record Type Composition”Include fields from other record types using spread syntax:
type BaseProps { className: string, disabled: boolean,}
type ButtonProps { ...BaseProps, onClick: fn() -> (), label: string,}// ButtonProps has: className, disabled, onClick, labelMultiple spreads are allowed:
type A { x: number }type B { y: string }type C { ...A, ...B, z: boolean }Rules:
- Spread must reference a record type (not a union or alias)
- Field name conflicts between spreads or with direct fields are compile errors
- The resulting type is a flat record
Union Types
Section titled “Union Types”Discriminated unions with variants:
type Color { | Red | Green | Blue | Custom { r: number, g: number, b: number }}Qualified Variants
Section titled “Qualified Variants”When a variant name could be ambiguous (e.g., multiple unions have a variant called Active), use qualified syntax:
type Filter { | All | Active | Completed }
const f = Filter.Allconst g = Filter.ActiveThis is especially useful when passing variants as arguments:
setFilter(Filter.Completed)Unambiguous variants can still be used without qualification:
match filter { All -> showAll(), Active -> showActive(), Completed -> showCompleted(),}String Literal Unions
Section titled “String Literal Unions”For npm interop with TypeScript libraries that use string literal unions:
type HttpMethod = "GET" | "POST" | "PUT" | "DELETE"type Status = "loading" | "error" | "success"Match on them with exhaustiveness checking:
fn describe(method: HttpMethod) -> string { match method { "GET" -> "fetching", "POST" -> "creating", "PUT" -> "updating", "DELETE" -> "removing", }}// Compiler error if you miss a variantString literal unions compile to the same TypeScript type:
type HttpMethod = "GET" | "POST" | "PUT" | "DELETE";For pure Floe code, prefer regular tagged unions (| Get | Post) since they work with constructors, for-blocks, and provide better type safety. String literal unions exist primarily for seamless npm interop.
Result and Option
Section titled “Result and Option”Result
Section titled “Result”For operations that can fail:
type Result<T, E> { | Ok { T } | Err { E } }
const result = Ok(42)const error = Err("something went wrong")Option
Section titled “Option”For values that may be absent:
type Option<T> { | Some { T } | None }
const found = Some("hello")const missing = NoneThe ? Operator
Section titled “The ? Operator”Propagate errors concisely:
fn getUsername(id: string) -> Result<string, Error> { const user = fetchUser(id)? // returns Err early if it fails Ok(user.name)}Brand Types
Section titled “Brand Types”Compile-time distinct types that erase at runtime:
type UserId = Brand<string, "UserId">type PostId = Brand<string, "PostId">
// userId and postId are both strings at runtime,// but can't be mixed up at compile timeOpaque Types
Section titled “Opaque Types”Types where only the defining module can see the internal structure:
opaque type Email = string
// Only this module can construct/destructure Email valuesTuple Types
Section titled “Tuple Types”Anonymous lightweight product types:
const point: (number, number) = (10, 20)const entry: (string, number) = ("key", 42)Destructure with pattern matching:
const (x, y) = point
fn divmod(a: number, b: number) -> (number, number) { (a / b, a % b)}
match divmod(10, 3) { (_, 0) -> "divides evenly", (q, r) -> `${q} remainder ${r}`,}Tuples compile to TypeScript readonly tuples: (number, string) becomes readonly [number, string], and (1, "a") becomes [1, "a"] as const.
Type Aliases
Section titled “Type Aliases”type Name = stringtype Callback = fn(Event) -> ()What’s Banned
Section titled “What’s Banned”| Banned | Why | Use Instead |
|---|---|---|
any | Disables type checking | unknown + narrowing |
null | Nullable reference bugs | Option<T> |
undefined | Redundant with null | Option<T> |
enum | Compiles to runtime objects | Union types |
interface | Redundant with type | type |