DEV Community

Jeroen van der Heijden
Jeroen van der Heijden

Posted on

🚀 ThingsDB v1.8.2: Introducing Anonymous Types

Developers using ThingsDB (or other data solutions) often run into a common pattern: you have a defined, complex type, but when you query it, you only need a subset of its fields.

Example: If you have a User type with fields like name, email, and password_hash, you can't just return the entire thing to a client. Before v1.8.2, your options were:

  • Define a second, wrap-only type (e.g., _User) to exclude the sensitive fields.
  • Manually construct a map of the desired fields.

ThingsDB v1.8.2 introduces an new solution with Anonymous Types.

âš¡ The Solution: Anonymous Type

Anonymous types allow you to define a temporary, ad-hoc type structure precisely where you need it, most often for defining the output of a query or a method call like wrap() or map_wrap().

The syntax is simple and powerful: the ampersand (&) prefix followed by a standard type definition.

Let's look at the classic use case—safely projecting data from a registered type.

// 1. Define the full type
set_type('User', {
    name: 'str',
    email: 'str',
    password_hash: 'str', // SENSITIVE FIELD
});

// 2. For simplicity, we create a list with a single User instance.
.users = [User{
    name: 'Jeroen van der Heijden',
    email: 'jeroen@cesbit.com',
    password_hash: 'SGVsbG8gVGhpbmdzREIhCg==',
}];

// 3. Use an ANONYMOUS TYPE to define the public output
// We only expose 'id', 'name', and 'email', securely omitting the hash.
.users.map_wrap(&{
    id: '#',        // '#' maps to the internal ID of the Thing
    name: 'str',
    email: 'str'
});
Enter fullscreen mode Exit fullscreen mode

Result (JSON):

[
    {
        "id": 123456,
        "name": "Jeroen van der Heijden",
        "email": "jeroen@cesbit.com"
    }
]
Enter fullscreen mode Exit fullscreen mode

No extra type definition needed! The anonymous type ensures type safety and validation on the projected fields without cluttering your global type registry.

📈 Beyond Simplicity: The Optimization Advantage

The &{...} literal syntax isn't just a convenience—it's a performance booster.

Unlike the alternative, ano(...), which constructs the type definition at runtime, the literal &{...} syntax allows the ThingsDB compiler to:

  • Generate optimal internal code for the data structure.
  • Bypass runtime overhead for type creation.

Key Takeaway: Always prefer &{...} for static definitions. Only use the ano(...) function when the type structure must be built dynamically based on runtime variables or input.

🔗 Advanced Use Cases: Complex Anonymous Structures

Anonymous types support the full richness of ThingsDB's type system, including arrays and nested structures.

Example:

// Nested output structure
&{
    request_id: '#',
    audit_trail: [{   // An array of audit check objects
        user_id: '#',
        timestamp: 'int',
        status: '*enum', // Match an existing Enum definition
    }],
    total_records: |this| this.audit_trail.len(),  // Computed
}
Enter fullscreen mode Exit fullscreen mode

This single block creates a temporary, highly-structured schema for an output object.

Upgrade to ThingsDB v1.8.2 today and start enjoying the freedom and speed of on-the-fly type definition!

Top comments (0)