Skip to content

Surqlize for TypeScript

Type inference

Surqlize derives every type from your schema, without a code generation step. When you need a named type, for a function signature or a shared interface, you extract it from the schema or from a query.

The examples below use this setup. The ORM is not connected, because the examples only read types.

Setup for the examples
import { Surreal } from "surrealdb";
import { orm, table, t } from "surqlize";

const user = table("user", { name: t.string(), age: t.number() });
const db = orm(new Surreal(), user);

t.infer<> gives the result type of a query.

The result type of a query
import { t } from "surqlize";

const query = db.select("user").return((user) => ({
    name: user.name,
    age: user.age,
}));

type QueryResult = t.infer<typeof query>;
// QueryResult: { name: string; age: number }[]

The type follows the query. .only() gives a single object instead of an array, .return() changes the shape, and .fetch() replaces record links with the records they point to.

A table or edge has a type property that holds the type of a stored record. Read it with typeof.

The type of a stored record
import { table, t } from "surqlize";

const account = table("account", {
    name: t.string(),
    age: t.number(),
});

type Account = (typeof account)["type"];
// Account: { id: RecordId<"account">; name: string; age: number }

For a table with computed fields, the type includes them. For a table linked to a class, it is the declared fields combined with the instance type of the class.

t.infer<> also works on a single field type.

The type of a field
const email = t.string();

type Email = t.infer<typeof email>;
// Email: string

CreateInput<> is the type that .content() accepts on create. It takes the schema of a table. Fields that have a .default() and fields of type t.option() are optional. Computed fields and id are left out.

The input of a create
import { type CreateInput, t, table } from "surqlize";

const profile = table("profile", {
    name: t.string(),
    isVerified: t.bool().default(false),
    nickname: t.option(t.string()),
});

type NewProfile = CreateInput<(typeof profile)["schema"]>;
// NewProfile: {
//     name: string;
//     isVerified?: boolean | undefined;
//     nickname?: string | undefined;
// }

The same type is what safeParse() and parse() return in their default "create" mode.

Every table, whether or not it is linked to a class, is assignable to the bare TableSchema type, so a helper that accepts any table can take it as a parameter.

Accept any table
import type { TableSchema } from "surqlize";

function tableName(schema: TableSchema) {
    return schema.tb;
}

tableName(user);

The ORM has a type too. Orm<[typeof post]> is the type to give the db parameter of a computed field expression, with the tuple listing the tables that the expression queries.

Was this page helpful?