# Moose / Olap / Supported Types Documentation – TypeScript
## Included Files
1. moose/olap/supported-types/supported-types.mdx
## Supported Column Types
Source: moose/olap/supported-types/supported-types.mdx
Complete guide to defining columns for ClickHouse tables in Moose
# Supported Column Types
Moose supports a comprehensive set of ClickHouse column types across both TypeScript and Python libraries. This guide covers all supported types, their syntax, and best practices for defining table schemas.
## Basic Types
### String Types
```typescript
interface User {
string: string; // String
lowCardinality: string & LowCardinality; // LowCardinality(String)
uuid: string & tags.Format<"uuid">; // UUID (with typia tags)
}
```
| ClickHouse Type | TypeScript | Description |
|------|------------|--------|
| `String` | `string` | Variable-length string |
| `LowCardinality(String)` | `string & LowCardinality` | Optimized for repeated values |
| `UUID` | `string & tags.Format<"uuid">` | UUID format strings |
### Numeric Types
### Integer Types
```typescript
interface Metrics {
user_id: Int32; // Int32
count: UInt64; // UInt64
small_value: Int8; // Int8
}
// Alternative: You can still use the verbose syntax if preferred
interface MetricsVerbose {
user_id: number & ClickHouseInt<"int32">;
count: number & ClickHouseInt<"uint64">;
small_value: number & ClickHouseInt<"int8">;
}
```
| ClickHouse Type | TypeScript (New Helper) | TypeScript (Verbose) | Description |
|------|------------|------------|--------|
| `Int8` | `Int8` | `number & ClickHouseInt<"int8">` | -128 to 127 |
| `Int16` | `Int16` | `number & ClickHouseInt<"int16">` | -32,768 to 32,767 |
| `Int32` | `Int32` | `number & ClickHouseInt<"int32">` | -2,147,483,648 to 2,147,483,647 |
| `Int64` | `Int64` | `number & ClickHouseInt<"int64">` | -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 |
| `UInt8` | `UInt8` | `number & ClickHouseInt<"uint8">` | 0 to 255 |
| `UInt16` | `UInt16` | `number & ClickHouseInt<"uint16">` | 0 to 65,535 |
| `UInt32` | `UInt32` | `number & ClickHouseInt<"uint32">` | 0 to 4,294,967,295 |
| `UInt64` | `UInt64` | `number & ClickHouseInt<"uint64">` | 0 to 18,446,744,073,709,551,615 |
### Floating Point Types
```typescript
interface SensorData {
temperature: Float32; // Float32
humidity: Float64; // Float64
pressure: number; // Default Float64
}
// Alternative: You can still use the verbose syntax if preferred
interface SensorDataVerbose {
temperature: number & tags.Type<"float">; // Float32
humidity: number; // Float64
}
```
| ClickHouse Type | TypeScript (New Helper) | TypeScript (Verbose) | Description |
|-----------------|------------|------------|---------------------|
| `Float32` | `Float32` | `number & tags.Type<"float">` | 32-bit floating point |
| `Float64` | `Float64` or `number` | `number` | 64-bit floating point (default) |
### Decimal Types
```typescript
interface FinancialData {
amount: Decimal<10, 2>; // Decimal(10,2)
rate: Decimal<5, 4>; // Decimal(5,4)
fee: Decimal<8, 3>; // Decimal(8,3)
}
// Alternative: You can still use the verbose syntax if preferred
interface FinancialDataVerbose {
amount: string & ClickHouseDecimal<10, 2>; // Decimal(10,2)
rate: string & ClickHouseDecimal<5, 4>; // Decimal(5,4)
}
```
| ClickHouse Type | TypeScript (New Helper) | TypeScript (Verbose) | Description |
|------|------------|------------|---------------------|
| `Decimal(P,S)` | `Decimal
` | `string & ClickHouseDecimal
` | Fixed-point decimal with P total digits, S decimal places |
### Boolean Type
```typescript
interface User {
is_active: boolean;
verified: boolean;
}
```
| ClickHouse Type | TypeScript | Description |
|------|------------|--------|
| `Boolean` | `boolean` | `boolean` |
### Date and Time Types
```typescript
interface Event {
created_at: DateTime; // DateTime
updated_at: DateTime64<3>; // DateTime(3)
logged_at: DateTime64<6>; // DateTime(6) - microsecond precision
birth_date: Date; // Date
}
// Alternative: You can still use the verbose syntax if preferred
interface EventVerbose {
created_at: Date; // DateTime
updated_at: Date & ClickHousePrecision<3>; // DateTime(3)
birth_date: Date; // Date
}
```
| ClickHouse Type | TypeScript (New Helper) | TypeScript (Verbose) | Description |
|-----------------|------------|------------|-------------|
| `Date` | `Date` | `Date` | Date only |
| `Date16` | `Date` | `Date` | Compact date format |
| `DateTime` | `DateTime` | `Date` | Date and time |
| `DateTime(P)` | `DateTime64` | `Date & ClickHousePrecision` | DateTime with precision (P=0-9) |
### Network Types
```typescript
interface NetworkEvent {
source_ip: string & tags.Format<"ipv4">;
dest_ip: string & tags.Format<"ipv6">;
}
```
| ClickHouse Type | TypeScript | Description |
|------|------------|--------|
| `IPv4` | `string & tags.Format<"ipv4">` | IPv4 addresses |
| `IPv6` | `string & tags.Format<"ipv6">` | IPv6 addresses |
## Complex Types
### Geometry Types
Moose supports ClickHouse geometry types. Use the helpers in each language to get type-safe models and correct ClickHouse mappings.
```typescript
ClickHousePoint,
ClickHouseRing,
ClickHouseLineString,
ClickHouseMultiLineString,
ClickHousePolygon,
ClickHouseMultiPolygon,
} from "@514labs/moose-lib";
interface GeoTypes {
point: ClickHousePoint; // Point → [number, number]
ring: ClickHouseRing; // Ring → Array<[number, number]>
lineString: ClickHouseLineString; // LineString → Array<[number, number]>
multiLineString: ClickHouseMultiLineString; // MultiLineString → Array>
polygon: ClickHousePolygon; // Polygon → Array>
multiPolygon: ClickHouseMultiPolygon; // MultiPolygon → Array>>
}
```
| ClickHouse Type | TypeScript |
|------|------------|
| `Point` | `ClickHousePoint` |
| `Ring` | `ClickHouseRing` |
| `LineString` | `ClickHouseLineString` |
| `MultiLineString` | `ClickHouseMultiLineString` |
| `Polygon` | `ClickHousePolygon` |
| `MultiPolygon` | `ClickHouseMultiPolygon` |
Geometry coordinates are represented as numeric pairs `[x, y]` (TypeScript) or `tuple[float, float]` (Python).
### Array Types
Arrays are supported for all basic types and some complex types.
```typescript
interface User {
tags: string[]; // Array(String)
scores: number[]; // Array(Float64)
metadata: Record[]; // Array(Json)
tuple: {
name: string;
age: number;
} & ClickHouseNamedTuple[]; // Array(Tuple(String, Int32))
}
```
### Map Types
Maps store key-value pairs with specified key and value types.
```typescript
interface User {
preferences: Record; // Map(String, String)
metrics: Record; // Map(String, Float64)
}
```
### Nested Types
Nested types allow embedding complex objects within tables.
```typescript
interface Address {
street: string;
city: string;
zip: string;
}
interface User {
name: string;
address: Address; // Nested type
}
```
### Named Tuple Types
Named tuples provide structured data with named fields.
```typescript
interface Point {
x: number;
y: number;
}
interface Shape {
center: Point & ClickHouseNamedTuple; // Named tuple
radius: number;
}
```
### Enum Types
Enums map to ClickHouse enums with string or integer values.
```typescript
enum UserRole {
ADMIN = "admin",
USER = "user",
GUEST = "guest"
}
interface User {
role: UserRole; // Enum with string values
}
```
## Special Types
### JSON Type
The `Json` type stores arbitrary JSON data with optional schema configuration for performance and type safety.
#### Basic JSON (Unstructured)
For completely dynamic JSON data without any schema:
```typescript
interface Event {
metadata: Record; // Basic JSON - accepts any structure
config: any; // Basic JSON - fully dynamic
}
```
#### Rich JSON with Type Configuration
For better performance and validation, you can define typed fields within your JSON using `ClickHouseJson`. This creates a ClickHouse `JSON` column with explicit type hints for specific paths.
```typescript
// Define the structure for your JSON payload
interface PayloadStructure {
name: string;
count: number;
timestamp?: Date;
}
interface Event {
id: string;
// JSON with typed paths - better performance, allows extra fields
payload: PayloadStructure & ClickHouseJson;
// JSON with performance tuning options
metadata: PayloadStructure & ClickHouseJson<
256, // max_dynamic_paths: limit tracked paths (default: no limit)
16, // max_dynamic_types: limit type variations (default: no limit)
["skip.me"], // skip_paths: exclude specific paths
["^tmp\\."] // skip_regexps: exclude paths matching regex
>;
}
```
#### Configuration Options
| Option | Type | Description |
|--------|------|-------------|
| `max_dynamic_paths` | `number` | Maximum number of unique JSON paths to track. Helps control memory usage for highly variable JSON structures. |
| `max_dynamic_types` | `number` | Maximum number of type variations allowed per path. Useful when paths may contain different types. |
| `skip_paths` | `string[]` | Array of exact JSON paths to ignore during ingestion (e.g., `["temp", "debug.info"]`). |
| `skip_regexps` | `string[]` | Array of regex patterns for paths to exclude (e.g., `["^tmp\\.", ".*_internal$"]`). |
#### Benefits of Typed JSON
1. **Better Performance**: ClickHouse can optimize storage and queries for known paths
2. **Type Safety**: Validates that specified paths match expected types
3. **Flexible Schema**: Allows additional fields beyond typed paths
4. **Memory Control**: Configure limits to prevent unbounded resource usage
- **Basic JSON** (`any`, `Dict[str, Any]`): Use when JSON structure is completely unknown or rarely queried
- **Rich JSON** (`ClickHouseJson`): Use when you have known fields that need indexing/querying, but want to allow additional dynamic fields
#### Example: Product Event Tracking
```typescript
interface ProductProperties {
category: string;
price: number;
inStock: boolean;
}
interface ProductEvent {
eventId: Key;
timestamp: DateTime;
// Typed paths for common fields, but allows custom properties
properties: ProductProperties & ClickHouseJson<
128, // Track up to 128 unique paths
8, // Allow up to 8 type variations per path
["_internal"], // Ignore internal fields
["^debug_"] // Ignore debug fields
>;
}
```
With this schema, you can send events like:
```json
{
"eventId": "evt_123",
"timestamp": "2025-10-22T12:00:00Z",
"properties": {
"category": "electronics", // Typed field ✓
"price": 99.99, // Typed field ✓
"inStock": true, // Typed field ✓
"customTag": "holiday-sale", // Extra field - accepted ✓
"brandId": 42, // Extra field - accepted ✓
"_internal": "ignored" // Skipped by skip_paths ✓
}
}
```
### Nullable Types
All types support nullable variants using optional types.
```typescript
interface User {
name: string; // Required
email?: string; // Nullable
age?: number; // Nullable
}
```
If a field is optional in your app model but you provide a ClickHouse default, Moose infers a non-nullable ClickHouse column with a DEFAULT clause.
- Optional without default (e.g., `field?: number`) → ClickHouse Nullable type.
- Optional with default (e.g., `field?: number & ClickHouseDefault<"18">` or `WithDefault`) → non-nullable column with default `18`.
This lets you keep optional fields at the application layer while avoiding Nullable columns in ClickHouse when a server-side default exists.
### SimpleAggregateFunction
`SimpleAggregateFunction` is designed for use with `AggregatingMergeTree` tables. It stores pre-aggregated values that are automatically merged when ClickHouse combines rows with the same primary key.
```typescript
interface DailyStats {
date: DateTime;
userId: string;
totalViews: number & SimpleAggregated<"sum", number>;
maxScore: number & SimpleAggregated<"max", number>;
lastSeen: DateTime & SimpleAggregated<"anyLast", DateTime>;
}
const statsTable = new OlapTable("daily_stats", {
engine: ClickHouseEngines.AggregatingMergeTree,
orderByFields: ["date", "userId"],
});
```
See [ClickHouse docs](https://clickhouse.com/docs/en/sql-reference/data-types/simpleaggregatefunction) for the complete list of functions.
## Table Engines
Moose supports all common ClickHouse table engines:
| Engine | Python | Description |
|--------|------------|-------------|
| `MergeTree` | `ClickHouseEngines.MergeTree` | Default engine |
| `ReplacingMergeTree` | `ClickHouseEngines.ReplacingMergeTree` | Deduplication |
| `SummingMergeTree` | `ClickHouseEngines.SummingMergeTree` | Aggregates numeric columns |
| `AggregatingMergeTree` | `ClickHouseEngines.AggregatingMergeTree` | Advanced aggregation |
| `ReplicatedMergeTree` | `ClickHouseEngines.ReplicatedMergeTree` | Replicated version of MergeTree |
| `ReplicatedReplacingMergeTree` | `ClickHouseEngines.ReplicatedReplacingMergeTree` | Replicated with deduplication |
| `ReplicatedSummingMergeTree` | `ClickHouseEngines.ReplicatedSummingMergeTree` | Replicated with aggregation |
| `ReplicatedAggregatingMergeTree` | `ClickHouseEngines.ReplicatedAggregatingMergeTree` | Replicated with advanced aggregation |
```typescript
const userTable = new OlapTable("users", {
engine: ClickHouseEngines.ReplacingMergeTree,
orderByFields: ["id", "updated_at"]
});
```
## Best Practices
### Type Selection
- **Use specific integer types** when you know the value ranges to save storage
- **Prefer `Float64`** for most floating-point calculations unless storage is critical
- **Use `LowCardinality`** for string columns with repeated values
- **Choose appropriate DateTime precision** based on your accuracy needs
### Performance Considerations
- **Order columns by cardinality** (low to high) for better compression
- **Use `ReplacingMergeTree`** for tables with frequent updates
- **Specify `orderByFields` or `orderByExpression`** for optimal query performance
- **Consider `LowCardinality`** for string columns with < 10,000 unique values