Powerful pattern matching and conditional expressions
Exhaustive pattern matching and functional conditionals without early returns
Powerful pattern matching and conditional expressions.
Match provides exhaustive pattern matching for Scala-style case expressions, while Cond offers functional conditional evaluation without early returns or if-else chains.
import { Match } from "functype/conditional"
const result = Match(statusCode)
.case(200, () => "OK")
.case(404, () => "Not Found")
.case(500, () => "Server Error")
.default(() => "Unknown")
const describe = Match(value)
.case(
(v): v is string => typeof v === "string",
(s) => `String: ${s}`,
)
.case(
(v): v is number => typeof v === "number",
(n) => `Number: ${n}`,
)
.case(
(v): v is boolean => typeof v === "boolean",
(b) => `Boolean: ${b}`,
)
.default(() => "Unknown type")
Option, Either, Try, and other types have built-in match methods:
// Option match
const greeting = Option(name).match({
Some: (n) => `Hello, ${n}!`,
None: () => "Hello, stranger!",
})
// Either match
const message = result.match({
Left: (error) => `Error: ${error}`,
Right: (value) => `Success: ${value}`,
})
// Try match
const output = tryValue.match({
Success: (v) => `Got: ${v}`,
Failure: (e) => `Failed: ${e.message}`,
})
Cond provides conditional expressions without early returns:
import { Cond } from "functype/conditional"
const grade = Cond<string>()
.when(score >= 90, () => "A")
.when(score >= 80, () => "B")
.when(score >= 70, () => "C")
.when(score >= 60, () => "D")
.otherwise(() => "F")
const category = Cond<string>()
.when(age < 13, () => "child")
.when(age < 20, () => "teenager")
.when(age < 65, () => "adult")
.otherwise(() => "senior")
Cond evaluates lazily - only the matching branch runs:
const result = Cond<number>()
.when(true, () => 1) // This runs
.when(true, () => expensiveCompute()) // This doesn't run
.otherwise(() => 0)
| Feature | Match | Cond |
|---|---|---|
| Input | Single value to match against | No input, checks conditions |
| Use Case | Value-based branching | Predicate-based branching |
| Pattern | Match(value).case(...) | Cond().when(...) |
// Matching on specific values
Match(httpMethod)
.case("GET", () => handleGet())
.case("POST", () => handlePost())
.case("PUT", () => handlePut())
.default(() => handleOther())
// Matching on discriminated unions
Match(action.type)
.case("INCREMENT", () => state + 1)
.case("DECREMENT", () => state - 1)
.case("RESET", () => 0)
.default(() => state)
// Complex conditional logic
const shipping = Cond<number>()
.when(order.total > 100, () => 0)
.when(order.isPrime, () => 0)
.when(order.isLocal, () => 5)
.otherwise(() => 10)
// Replacing if-else chains
const message = Cond<string>()
.when(errors.length > 0, () => `${errors.length} errors found`)
.when(warnings.length > 0, () => `${warnings.length} warnings`)
.otherwise(() => "All good!")
// Traditional if-else (imperative)
let result: string
if (status === 200) {
result = "OK"
} else if (status === 404) {
result = "Not Found"
} else {
result = "Unknown"
}
// Match (functional expression)
const result = Match(status)
.case(200, () => "OK")
.case(404, () => "Not Found")
.default(() => "Unknown")
See full API documentation at functype API docs