Unions & Intersections
Combine schemas with union and intersection types
Union Types
Match any of the specified schemas:
import { union, str, num, bool } from '@sylphx/vex'
const stringOrNumber = union(str(), num())
stringOrNumber('hello') // ✅ 'hello'
stringOrNumber(42) // ✅ 42
stringOrNumber(true) // ❌ throwsLiteral Unions
Common for status/enum-like values:
import { union, literal } from '@sylphx/vex'
const status = union(
literal('pending'),
literal('active'),
literal('done')
)
status('active') // ✅ 'active'
status('invalid') // ❌ throwsDiscriminated Unions
Use a common field to distinguish types:
import { union, object, str, num, literal } from '@sylphx/vex'
const successSchema = object({
type: literal('success'),
data: str(),
})
const errorSchema = object({
type: literal('error'),
message: str(),
code: num(),
})
const responseSchema = union(successSchema, errorSchema)
responseSchema({ type: 'success', data: 'Hello' })
// ✅ { type: 'success', data: 'Hello' }
responseSchema({ type: 'error', message: 'Failed', code: 500 })
// ✅ { type: 'error', message: 'Failed', code: 500 }Intersection Types
Combine multiple schemas:
import { intersect, object, str, num } from '@sylphx/vex'
const withId = object({ id: str() })
const withTimestamp = object({ createdAt: num() })
const entitySchema = intersect(withId, withTimestamp)
entitySchema({ id: '123', createdAt: 1234567890 })
// ✅ { id: '123', createdAt: 1234567890 }Optional Union Members
import { union, str, undefinedType } from '@sylphx/vex'
// string | undefined
const optionalString = union(str(), undefinedType())
optionalString('hello') // ✅
optionalString(undefined) // ✅