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)