> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ubiquex.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Types

> All type expressions valid in XCL input fields and type annotations.

Type expressions appear in `input` block field declarations. The typechecker validates that types are well-formed and that default values are type-compatible.

## Primitive types

| Type     | Description      | Python config accessor                          |
| -------- | ---------------- | ----------------------------------------------- |
| `string` | UTF-8 string     | `config.get()` / `config.require()`             |
| `bool`   | Boolean          | `config.get_bool()` / `config.require_bool()`   |
| `number` | Integer or float | `config.get_float()` / `config.require_float()` |
| `int`    | Integer          | `config.get_int()` / `config.require_int()`     |
| `any`    | Unconstrained    | `config.require_object()`                       |

```xcl theme={"theme":"css-variables"}
input "s" {
    name:    string
    enabled: bool   = true
    count:   int    = 1
    ratio:   number = 0.5
    meta:    any
}
```

## Collection types

### list(T)

An ordered sequence of values of type T:

```xcl theme={"theme":"css-variables"}
azs:         list(string)
port_ranges: list(int)
```

### set(T)

An unordered collection of unique values:

```xcl theme={"theme":"css-variables"}
allowed_ips: set(string)
```

### map(T)

A string-keyed map of values of type T:

```xcl theme={"theme":"css-variables"}
tags:         map(string)
replica_info: map(number)
```

### tuple(\[T1, T2, ...])

A fixed-length sequence with per-position types:

```xcl theme={"theme":"css-variables"}
endpoint: tuple([string, int])    // e.g. ["host", 5432]
```

## Object type

A record with named, typed fields:

```xcl theme={"theme":"css-variables"}
db_config: object({
    host: string
    port: int
    name: string
})
```

Object fields can themselves use any type expression.

## optional(T)

Makes any type optional with a `null` default:

```xcl theme={"theme":"css-variables"}
input "s" {
    extra_tags: optional(map(string))
}
```

With an explicit default:

```xcl theme={"theme":"css-variables"}
input "s" {
    timeout: optional(number, 30)
}
```

`optional(T)` means the field will be `null` if not set; `optional(T, default)` means the field will be `default` if not set.

## Named types

A dotted identifier path that names a provider-contributed or user-defined type:

```xcl theme={"theme":"css-variables"}
input "s" {
    nat_strategy: aws.ec2.NatStrategy
    cidr:         CIDR
}
```

Named types parse successfully. The typechecker verifies the path is non-empty but does not resolve it against provider schemas (schema validation is handled separately). At runtime, the value is treated as `any` for config reading purposes.

## Nested types

Types compose arbitrarily:

```xcl theme={"theme":"css-variables"}
input "s" {
    // list of objects
    subnet_configs: list(object({
        cidr: string
        az:   string
    }))

    // map of lists
    az_map: map(list(string))

    // optional list
    extra_cidrs: optional(list(string))
}
```

## Default value type checking

The typechecker catches obvious mismatches between default literal kinds and declared types:

| Mismatch                | Error                                                         |
| ----------------------- | ------------------------------------------------------------- |
| `name: string = 42`     | `default value is a number literal but field type is string`  |
| `name: string = true`   | `default value is a boolean literal but field type is string` |
| `count: number = "30s"` | `default value is a string literal but field type is number`  |
| `count: number = true`  | `default value is a boolean literal but field type is number` |
| `enabled: bool = "yes"` | `default value is a string literal but field type is bool`    |
| `enabled: bool = 1`     | `default value is a number literal but field type is bool`    |

Complex-type defaults (list, object, etc.) are not checked for full structural compatibility in the current typechecker — that is deferred to full type unification in a later phase.
