Type Functions (type::)
Type Functions (type::*)
Level 6 — Advanced Querying & Functions The standard library module in SurrealDB for inspecting data types at runtime, constructing Record IDs dynamically, and converting between types (
type::thing(),type::is::*(),type::table(),type::field()).
1. Prerequisites
- Built-in Functions Overview — The parent library context.
- Type Casting & Coercion — Explicit casting.
2. Term Category
Query Feature (type checking & conversion builtin functions): - Database Command / Tool
3. Explanation
(1) Design Motivation — "Why did we design this?"
Dynamic applications frequently need to inspect or construct data structures at runtime:
- Constructing a Record ID dynamically from variable strings (e.g. joining table name
"user"and ID string"alice"to produce the primitiverecordtokenuser:alice). - Inspecting incoming data types dynamically inside validation triggers or generic functions (e.g. checking if a field is a string before running text functions).
- Extracting table name or ID strings from Record ID tokens.
In PostgreSQL, type checking uses system catalog queries (pg_typeof()). In MongoDB, type checks use $type aggregation operators.
We designed the type::* module in SurrealDB to provide a complete type introspection and construction library. Functions like type::thing(table, id) allow you to safely build valid Record IDs without risky string concatenation, while type::is::* helpers provide clean boolean runtime type checks.
(2) Key Function Categories
1. Record ID Construction & Extraction
type::thing(table, id): Constructs a native Record ID token (e.g.type::thing("user", "alice")user:alice).type::table(record_id): Extracts the table name string from a Record ID (e.g.type::table(user:alice)"user").type::id(record_id): Extracts the ID portion string/number from a Record ID (e.g.type::id(user:alice)"alice").
2. Runtime Type Inspection (type::is::*)
type::is::string(val)/type::is::number(val)/type::is::record(val)type::is::array(val)/type::is::object(val)/type::is::datetime(val)- Returns
trueif the value matches the target data type.
3. Explicit Type Conversion Helpers
type::bool(val)/type::int(val)/type::string(val)/type::datetime(val)- Functional alternatives to the prefixed angle-bracket casting operator (
<type> val).
(3) Reality Metaphor (The ID Badge Machine)
Imagine a security credential desk:
type::thing: Taking a blank plastic badge, printing the building name"user"on top, stamping the employee name"alice"below, and encoding a magnetic chip. It outputs an official, valid Security Badge Token (user:alice).type::table: Reading an employee's badge and noting down only the building name where they work.type::is::string: A sensor scanning a badge to verify whether it is made of plastic or metal.
(4) Code Examples
Using type::* Functions in SurrealQL
-- 1. Constructing Record IDs dynamically from script parameters
LET $tbl = "product";
LET $key = "laptop_100";
LET $target_id = type::thing($tbl, $key); -- Evaluates to primitive token product:laptop_100
SELECT * FROM $target_id;
-- 2. Extracting table and ID components from record links
SELECT
id,
type::table(id) AS table_name,
type::id(id) AS id_value
FROM user:tobie;
-- Returns: table_name = "user", id_value = "tobie"
-- 3. Runtime type checking inside conditional logic
SELECT
title,
IF type::is::array(tags) THEN array::len(tags) ELSE 0 END AS tag_count
FROM post;
4. Common Mistakes & Pitfalls
Mistake 1: Concatenating strings to construct Record IDs instead of using 'type::thing()', resulting in string types rather than record tokens
The mistake: Writing LET $rec = $tbl + ":" + $id; expecting $rec to be a valid record token.
Why it's wrong: String concatenation produces a string data type ("user:alice" with quotes). Passing a string into record link fields or FROM targets causes type mismatches and disables direct pointer traversals.
Fix: Use type::thing(table, id) to construct genuine Record ID tokens:
-- BAD (creates string "user:alice")
LET $rec = "user" + ":" + "alice";
-- GOOD (creates record token user:alice)
LET $rec = type::thing("user", "alice");
Mistake 2: Confusing type::is:: Inspection Functions with Type Casting <type>
The mistake: Writing type::is::number("123") expecting it to convert the string to a number.
Why it's wrong: type::is::number() is a boolean inspection function returning false for strings! Use <number> "123" or type::number("123") to perform type conversion.
Incorrect:
LET $num = type::is::number("123"); // ❌ Returns false boolean, does NOT convert!
Fix:
LET $num = <number> "123"; // Performs type conversion to 123
Mistake 3: Using Invalid Type Strings in type::of() Comparisons
The mistake: Comparing type::of($val) = "String" with uppercase string names.
Why it's wrong: type::of() returns lowercase type names (e.g. "string", "number", "datetime", "record", "array", "object").
Incorrect:
IF type::of($val) = "String" { ... }; // ❌ Case mismatch!
Fix:
IF type::of($val) = "string" { ... }; // Lowercase type string
5. Practice Exercises
Exercise 1: Inspecting Value Types with type::of()
Scenario:
Inspect the native SurrealDB data type of various literals ("text", 100.00dec, d"2026-08-06", user:alice) using type::of().
Requirements:
- Execute
type::of()over string, decimal, datetime, and record link values.
Answer
Implementation
SELECT
type::of("text") AS str_t,
type::of(100.00dec) AS dec_t,
type::of(d"2026-08-06T00:00:00Z") AS dt_t,
type::of(user:alice) AS rec_t;
Technical Explanation
type::of(value)returns a string identifying the native SurrealDB data type.- Returns
"string","decimal","datetime","record","array","object", etc. - Used for type introspection in dynamic query scripts.
Exercise 2: Type Validation Checks with type::is::*
Scenario:
Validate whether an incoming parameter $val is a valid decimal type using type::is::decimal().
Requirements:
- Check
IF type::is::decimal($val) THEN ....
Answer
Exercise 3: Coercing Values with Type Conversion Functions
Scenario:
Convert string "150" to integer using type::int() and string "true" to boolean using type::bool().
Requirements:
- Select
type::int("150")andtype::bool("true").
Answer
Implementation
SELECT
type::int("150") AS int_val,
type::bool("true") AS bool_val;
Technical Explanation
type::int(),type::bool(),type::string(),type::datetime()explicitly coerce values to target types.- Provides function-style alternative to casting syntax (
<int> "150"). - Ensures payload type alignment prior to write commits.
6. Related Terms
- Built-in Functions Overview — The parent library.
- Type Casting & Coercion — Explicit casting.
- Record ID (
table:id) — Record ID format.
7. Key Takeaways
- The
type::*module handles dynamic type inspection, conversion, and construction. type::thing(table, id)constructs native Record ID tokens safely from strings.type::table(id)andtype::id(id)extract component strings from Record IDs.type::is::*()functions perform runtime boolean type checks.- Avoid string concatenation when building Record IDs to prevent string/token type bugs.