Skip to content

Migrating from TypeScript

Floe is designed to be familiar to TypeScript developers.

  • Import/export syntax
  • Template literals
  • JSX
  • Async (via |> await instead of keywords; return type is Promise<T>, or use async let f() -> T = { ... } sugar)
  • Type annotations
  • Generics
TypeScriptFloeExample
functionletlet greet(name: string) -> string = { ... }
: ReturnType-> ReturnTypelet add(a: number, b: number) -> number = ...
.filter().map()|> filter |> mapitems |> filter(.active) |> map(.name)
let / constlet onlyNo mutation
======= compiles to ===
switchmatchExhaustive, no fall-through
try/catchUntrusted imports (default)import { parseYaml } from "yaml-lib" (auto-wrapped in Result)
{x && <Comp />}Option.map{x |> Option.map((v) -> <Comp v={v} />)}
T | nullOption<T>Some(value) / None
throwResult<T, E>Ok(value) / Err(error)
async/await|> await + async letasync let f() -> T = { ... } or let f() -> Promise<T> = { ... }; call with expr |> await
FeatureWhyAlternative
const / varTwo binding keywords + mutability footgunslet only (always immutable)
classComplex inheritance hierarchiesFunctions + records
thisImplicit context bugsExplicit parameters
anyType safety escapeunknown + narrowing
null / undefinedNullable reference bugsOption<T>
enumCompiles to runtime objectsUnion types
interfaceRedundanttype
switchNo exhaustiveness, fall-throughmatch
for / whileMutation-heavyPipes + map/filter/reduce
throwInvisible error pathsResult<T, E>
returnImplicit returnsLast expression is the return value

Floe compiles to .ts/.tsx, so you can adopt it file by file. Write new files as .fl, compile them alongside your existing .ts files, and your build tool (Vite, Next.js) treats the output as normal TypeScript.