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

# Data Types

> Supported data types and type conversion in Cocobase

# Data Types

Cocobase supports all standard JSON data types plus additional type conversion utilities for strongly-typed applications.

## Primitive Types

### String

Text data of any length.

```typescript theme={null}
{
  "name": "Alice Johnson",
  "bio": "Full-stack developer passionate about clean code",
  "website": "https://alice.dev"
}
```

### Number

Integers and floating-point numbers.

```typescript theme={null}
{
  "age": 28,
  "price": 99.99,
  "rating": 4.5,
  "quantity": 100
}
```

<Note>
  Numbers are stored as IEEE 754 double-precision floating-point. Maximum safe
  integer: `2^53 - 1` (9,007,199,254,740,991)
</Note>

### Boolean

True or false values.

```typescript theme={null}
{
  "isActive": true,
  "emailVerified": false,
  "hasSubscription": true
}
```

### Null

Represents absence of a value.

```typescript theme={null}
{
  "middleName": null,
  "avatar": null
}
```

## Complex Types

### Object

Nested JSON objects for structured data.

```typescript theme={null}
{
  "address": {
    "street": "123 Main St",
    "city": "New York",
    "zipCode": "10001",
    "coordinates": {
      "lat": 40.7128,
      "lng": -74.0060
    }
  }
}
```

**Nesting limit:** 100 levels deep

### Array

Ordered collections of any type.

```typescript theme={null}
{
  "tags": ["javascript", "react", "nodejs"],
  "scores": [85, 92, 78, 95],
  "metadata": [
    { "key": "category", "value": "tech" },
    { "key": "priority", "value": 1 }
  ]
}
```

**Maximum length:** 100,000 elements

## Date and Time

Dates are stored as ISO 8601 strings.

```typescript theme={null}
{
  "createdAt": "2024-01-15T10:30:00Z",
  "publishDate": "2024-02-01T00:00:00Z",
  "lastLogin": "2024-01-20T14:45:30.123Z"
}
```

<Tabs>
  <Tab title="JavaScript">
    ```typescript theme={null}

    // Create with current date
    await db.collection("events").create({
    name: "Product Launch",
    date: new Date().toISOString(),
    });

    // Parse date from document
    const event = await db.collection("events").get("event_123");
    const date = new Date(event.date);

    console.log(date.toLocaleDateString()); // "1/15/2024"
    ```
  </Tab>

  <Tab title="Dart">
    ```dart theme={null}
    // Create with current date
    await db.createDocument('events', {
      'name': 'Product Launch',
      'date': DateTime.now().toIso8601String(),
    });

    // Parse date from document
    final event = await db.getDocument('events', 'event_123');
    final date = DateTime.parse(event['date']);
    print(date.toString());
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    // Create with current date
    db.CreateDocument(ctx, "events", map[string]any{
        "name": "Product Launch",
        "date": time.Now().Format(time.RFC3339),
    })

    // Parse date from document
    event, _ := db.GetDocument(ctx, "events", "event_123")
    date, _ := time.Parse(time.RFC3339, event["date"].(string))
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    from datetime import datetime

    # Create with current date
    db.create_document("events", {
        "name": "Product Launch",
        "date": datetime.now().isoformat()
    })

    # Parse date from document
    event = db.get_document("events", "event_123")
    date = datetime.fromisoformat(event['date'])
    ```
  </Tab>
</Tabs>

## Type Conversion (Flutter/Dart)

Flutter SDK provides type converters for type-safe operations.

### Defining Converters

```dart theme={null}
// models/user.dart
class User {
  final String id;
  final String name;
  final String email;
  final int age;
  final DateTime createdAt;

  User({
    required this.id,
    required this.name,
    required this.email,
    required this.age,
    required this.createdAt,
  });

  // From JSON
  factory User.fromJson(Map<String, dynamic> json) {
    return User(
      id: json['id'] as String,
      name: json['name'] as String,
      email: json['email'] as String,
      age: json['age'] as int,
      createdAt: DateTime.parse(json['createdAt'] as String),
    );
  }

  // To JSON
  Map<String, dynamic> toJson() {
    return {
      'name': name,
      'email': email,
      'age': age,
    };
  }
}
```

### Registering Converters

```dart theme={null}
// Register converters globally
db.registerConverter<User>(
  fromJson: (json) => User.fromJson(json),
  toJson: (user) => user.toJson(),
);

// Use typed operations
final user = await db.createDocument<User>('users', User(
  id: '',
  name: 'Alice',
  email: 'alice@example.com',
  age: 28,
  createdAt: DateTime.now(),
));

// user is strongly typed
print(user.name); // Alice
```

## TypeScript Type Definitions

Define interfaces for compile-time type safety:

```typescript theme={null}
interface Product {
  id: string;
  name: string;
  description: string;
  price: number;
  inStock: boolean;
  tags: string[];
  category: "electronics" | "clothing" | "books";
  metadata: {
    brand: string;
    sku: string;
  };
  createdAt: string;
  updatedAt: string;
}

// Type-safe operations
const product = await db.collection("products").create<Product>({
  name: "Laptop",
  description: "High-performance laptop",
  price: 1299.99,
  inStock: true,
  tags: ["computer", "electronics"],
  category: "electronics",
  metadata: {
    brand: "TechCorp",
    sku: "LAP-001",
  },
});

// TypeScript knows the shape
console.log(product.price); // ✅ number
console.log(product.foo); // ❌ Error: Property 'foo' does not exist
```

## Special Data Types

### File References

Store file URLs or references to uploaded files:

```typescript theme={null}
{
  "profilePicture": "https://storage.cocobase.cc/files/avatar.jpg",
  "documents": [
    "https://storage.cocobase.cc/files/resume.pdf",
    "https://storage.cocobase.cc/files/portfolio.pdf"
  ]
}
```

See [File Storage](/features/file-storage) for details.

### Document References

Store references to other documents:

```typescript theme={null}
{
  "userId": "user_123",           // Reference to user document
  "categoryId": "category_456",   // Reference to category document
  "relatedPosts": [               // Array of references
    "post_789",
    "post_012"
  ]
}
```

Use [population](/features/relationships) to fetch referenced documents.

### Geolocation

Store coordinates as nested objects:

```typescript theme={null}
{
  "location": {
    "lat": 40.7128,
    "lng": -74.0060,
    "accuracy": 10
  }
}
```

Query with range filters:

```typescript theme={null}
const nearbyPlaces = await db.collection("places").list({
  filters: {
    "location.lat": { $gte: 40.0, $lte: 41.0 },
    "location.lng": { $gte: -75.0, $lte: -73.0 },
  },
});
```

## Type Validation

While Cocobase is schema-less, you can implement validation in your application:

<Tabs>
  <Tab title="TypeScript/JavaScript">
    ### Using Zod

    ```typescript theme={null}
    import { z } from "zod";

    const UserSchema = z.object({
      name: z.string().min(1).max(100),
      email: z.string().email(),
      age: z.number().int().min(0).max(150),
      role: z.enum(["admin", "user", "moderator"]),
    });

    // Validate before creating
    const userData = {
      name: "Alice",
      email: "alice@example.com",
      age: 28,
      role: "user" as const,
    };

    const validatedData = UserSchema.parse(userData);
    await db.collection("users").create(validatedData);

    ```
  </Tab>

  <Tab title="Flutter/Dart">
    ### Manual Validation

    ```dart theme={null}
    class User {
      final String name;
      final String email;
      final int age;

      User({required this.name, required this.email, required this.age}) {
        // Validate in constructor
        if (name.isEmpty || name.length > 100) {
          throw ArgumentError('Name must be between 1 and 100 characters');
        }
        if (!email.contains('@')) {
          throw ArgumentError('Invalid email format');
        }
        if (age < 0 || age > 150) {
          throw ArgumentError('Age must be between 0 and 150');
        }
      }

      Map<String, dynamic> toJson() {
        return {'name': name, 'email': email, 'age': age};
      }
    }

    // Use validated model
    try {
      final user = User(name: 'Alice', email: 'alice@example.com', age: 28);
      await db.createDocument('users', user.toJson());
    } catch (e) {
      print('Validation error: $e');
    }
    ```
  </Tab>

  <Tab title="Go">
    ### Struct Validation

    ```go theme={null}
    type User struct {
        Name  string `json:"name"`
        Email string `json:"email"`
        Age   int    `json:"age"`
    }

    func (u *User) Validate() error {
        if len(u.Name) == 0 || len(u.Name) > 100 {
            return errors.New("name must be between 1 and 100 characters")
        }
        if !strings.Contains(u.Email, "@") {
            return errors.New("invalid email format")
        }
        if u.Age < 0 || u.Age > 150 {
            return errors.New("age must be between 0 and 150")
        }
        return nil
    }

    // Validate before creating
    user := &User{Name: "Alice", Email: "alice@example.com", Age: 28}
    if err := user.Validate(); err != nil {
        return err
    }
    db.CreateDocument(ctx, "users", user)
    ```
  </Tab>

  <Tab title="Python">
    ### Function Validation

    ```python theme={null}
    def validate_user(data):
        required = ['name', 'email', 'age']
        for field in required:
            if field not in data:
                raise ValueError(f"Missing required field: {field}")

        if not data['name'] or len(data['name']) > 100:
            raise ValueError("Name must be between 1 and 100 characters")

        if '@' not in data['email']:
            raise ValueError("Invalid email format")

        if not isinstance(data['age'], int) or data['age'] < 0 or data['age'] > 150:
            raise ValueError("Age must be between 0 and 150")

        return True

    # Validate before creating
    user_data = {
        "name": "Alice",
        "email": "alice@example.com",
        "age": 28
    }

    validate_user(user_data)
    db.create_document("users", user_data)
    ```
  </Tab>

  <Tab title="Cloud Functions">
    ### Server-Side Validation

    ```python theme={null}
    def main():
        data = req.json()

        # Validate required fields
        required = ['name', 'email', 'age']
        for field in required:
            if field not in data:
                return {"error": f"Missing required field: {field}"}, 400

        # Validate data types and constraints
        if not isinstance(data['age'], int) or data['age'] < 0:
            return {"error": "Age must be a positive integer"}, 400

        if '@' not in data['email']:
            return {"error": "Invalid email format"}, 400

        # Create document after validation
        user = db.create_document("users", data)
        return {"user": user}
    ```
  </Tab>
</Tabs>

## Type Coercion

Cocobase automatically handles some type conversions:

```typescript theme={null}
// Numbers
"42" → 42         // String to number in numeric context
42.0 → 42         // Float to int when whole number

// Booleans
"true" → true     // String to boolean
1 → true          // Number to boolean
0 → false

// Dates
"2024-01-15" → "2024-01-15T00:00:00Z"  // Date string normalization
```

<Warning>
  Automatic coercion is not guaranteed. Always store data in the correct type to
  avoid unexpected behavior.
</Warning>

## Best Practices

<AccordionGroup>
  <Accordion title="Use Consistent Types">
    Keep field types consistent across documents:

    ```typescript theme={null}
    // ✅ Good - Consistent types
    { "price": 99.99 }
    { "price": 149.99 }

    // ❌ Bad - Mixed types
    { "price": 99.99 }
    { "price": "149.99" }  // String instead of number
    ```
  </Accordion>

  <Accordion title="Store Dates as ISO Strings">
    Always use ISO 8601 format for dates:

    ```typescript theme={null}
    // ✅ Good
    { "date": "2024-01-15T10:30:00Z" }

    // ❌ Bad
    { "date": "01/15/2024" }        // Non-standard format
    { "date": 1705319400000 }       // Unix timestamp
    ```
  </Accordion>

  <Accordion title="Use Arrays for Ordered Data">
    Use arrays when order matters, objects when it doesn't:

    ```typescript theme={null}
    // ✅ Array for ordered list
    {
      "steps": ["Mix", "Bake", "Cool", "Serve"]
    }

    // ✅ Object for key-value pairs
    {
      "settings": {
        "theme": "dark",
        "language": "en",
        "notifications": true
      }
    }
    ```
  </Accordion>

  <Accordion title="Define TypeScript Interfaces">
    Always define interfaces for your data models:

    ```typescript theme={null}
    // ✅ Good - Clear interface
    interface Post {
      id: string;
      title: string;
      content: string;
      authorId: string;
      tags: string[];
      publishedAt: string;
    }

    // Use in operations
    const post = await db.createDocument<Post>("posts", {...});
    ```
  </Accordion>
</AccordionGroup>

## Type Limits

| Type     | Maximum Size/Length          |
| -------- | ---------------------------- |
| String   | 16 MB per document           |
| Number   | ±1.7976931348623157 × 10^308 |
| Array    | 100,000 elements             |
| Object   | 100 levels of nesting        |
| Document | 16 MB total size             |

## Next Steps

<CardGroup cols={2}>
  <Card title="Collections" icon="database" href="/core-concepts/collections">
    Learn about organizing data in collections
  </Card>

  <Card title="Flutter SDK" icon="mobile" href="/sdk-reference/flutter">
    Type-safe Flutter development
  </Card>

  <Card title="CRUD Operations" icon="pen" href="/features/crud-operations">
    Work with your typed data
  </Card>

  <Card title="Relationships" icon="link" href="/features/relationships">
    Connect documents with references
  </Card>
</CardGroup>
