---
audience: engineers
summary: Primitive types, compound types, enums, unions, named types, and how the
  type-checker reasons about them.
title: Type system
path: reference/language/type-system
status: published
---

### 3.1 Primitive Types

| Type | Description | Example Values |
|------|-------------|---------------|
| `string` | Text | `"hello"` |
| `int` | Integer | `42` |
| `float` | Decimal | `3.14` |
| `bool` | Boolean | `true`, `false` |
| `date` | Calendar date | `2026-01-15` |
| `datetime` | Timestamp | `2026-01-15T10:30:00Z` |
| `duration` | Time span | `30s`, `5m`, `1h` |
| `money` | Monetary value with currency | `1500.00` |
| `email` | Email address | `"user@example.com"` |
| `url` | URL | `"https://example.com"` |
| `uuid` | UUID | `"550e8400-e29b-41d4-a716-446655440000"` |

### 3.2 Collection Types

```scaicore
array[string]                    // Array of strings
array[LineItem]                  // Array of custom type
map[string, int]                 // String-keyed map
map[string, array[string]]       // Nested collections
```

### 3.3 Object Types (Inline)

```scaicore
// Inline object type in output declaration
output = {
    vendor: string,
    amount: money,
    items: array[{ description: string, quantity: int, price: money }]
}
```

### 3.4 Named Types

```scaicore
@types {
    type Invoice = {
        id: uuid,
        vendor: string,
        amount: money,
        status: InvoiceStatus,
        line_items: array[LineItem]
    }

    type LineItem = {
        description: string,
        quantity: int,
        unit_price: money,
        total: money,
        category: string?             // Optional field
    }
}
```

### 3.5 Enums (Compile-Time Checked Symbols)

```scaicore
type InvoiceStatus = enum[draft, pending, approved, rejected, paid]

// Usage — prefix with `:`
@rigid {
    invoice.status = :approved         // Compiler checks this is valid
}

// Exhaustiveness checking in match
match invoice.status {
    :draft => handle_draft()
    :pending => handle_pending()
    :approved => handle_approved()
    :rejected => handle_rejected()
    :paid => handle_paid()
    // Compiler warns if a case is missing
}
```

### 3.6 String Unions (Flexible Matching)

```scaicore
// String literal unions — for values that come from/go to LLMs
type Sentiment = "positive" | "negative" | "neutral" | "mixed"
type Priority = "low" | "medium" | "high" | "critical"

// Used in @flexible output — runtime validates LLM output matches
result = @flexible {
    goal = "classify sentiment"
    input = message
    output = { sentiment: Sentiment }
}
```

### 3.7 Union Types

```scaicore
type SearchResult = Customer | Vendor | Contact
type ApiResponse = SuccessResponse | ErrorResponse
```

### 3.8 Optional Types

```scaicore
type Customer = {
    name: string,                      // Required
    email: email?,                     // Optional (may be null)
    phone: string?                     // Optional
}
```

### 3.9 Type Inference

```scaicore
@rigid {
    count = 42                          // Inferred as int
    name = "Alice"                      // Inferred as string
    items = [1, 2, 3]                   // Inferred as array[int]
}

// Explicit annotation when needed
total: money = calculate_total(items)
```

---