• Start

Languages

/

JavaScript

/

API Reference

/

TypeScript Types

TypeScript types

TypeScript type definitions and interfaces used throughout the SDK.

The SDK provides comprehensive TypeScript type definitions for type-safe development. This page documents the key types and interfaces used throughout the SDK.

Represents the current connection state.

type ConnectionStatus = "disconnected" | "connecting" | "reconnecting" | "connected"

Example:

if (db.status === "connected") {
    console.log('Ready to execute queries');
}

Configuration options for the Surreal driver.

interface DriverOptions {
    engines?: Engines;
    codecs?: Codecs;
    codecOptions?: CodecOptions;
    websocketImpl?: typeof WebSocket;
    fetchImpl?: typeof fetch;
}

Properties:

  • engines - Custom engine factories for different protocols

  • codecs - Custom codec factories for encoding/decoding

  • codecOptions - Options for codec behavior

  • websocketImpl - Custom WebSocket implementation

  • fetchImpl - Custom fetch implementation

Example:

const db = new Surreal({
    codecOptions: {
        useNativeDates: true
    }
});

Options for establishing a connection.

interface ConnectOptions {
    namespace?: string;
    database?: string;
    authentication?: AuthProvider;
    versionCheck?: boolean;
    invalidateOnExpiry?: boolean;
    reconnect?: boolean | Partial<ReconnectOptions>;
    retry?: boolean | Partial<RetryOptions>;
}

Properties:

  • namespace - Namespace to use

  • database - Database to use

  • authentication - Authentication details or provider function

  • versionCheck - Enable version compatibility checking (default: true)

  • invalidateOnExpiry - Invalidate session on token expiry (default: false)

  • reconnect - Reconnection behavior configuration (default: true)

  • retry - Connection-wide default for retrying queries on write conflict (default: disabled)

Example:

await db.connect('ws://localhost:8000', {
    namespace: 'my_namespace',
    database: 'my_database',
    authentication: {
        username: 'root',
        password: 'root'
    },
    reconnect: {
        attempts: 10,
        retryDelay: 1000
    },
    retry: {
        enabled: true,
        attempts: 5,
        retryDelay: 100
    }
});

Configuration for automatic reconnection behavior.

interface ReconnectOptions {
    enabled: boolean;
    attempts: number;
    retryDelay: number;
    retryDelayMax: number;
    retryDelayMultiplier: number;
    retryDelayJitter: number;
    catch?: (error: Error) => boolean;
}

Properties:

  • enabled - Enable automatic reconnection

  • attempts - Maximum reconnection attempts (-1 for unlimited)

  • retryDelay - Initial delay before reconnecting (ms)

  • retryDelayMax - Maximum delay between attempts (ms)

  • retryDelayMultiplier - Multiply delay after each failed attempt

  • retryDelayJitter - Random offset percentage for delays

  • catch - Custom error handler for reconnection errors

Configuration for retrying a query, mutation, or transaction when it fails with a write conflict. Modeled on ReconnectOptions, and applied the same way: as a connection-wide default via ConnectOptions.retry, or per call via .retry().

interface RetryOptions {
    enabled: boolean;
    attempts: number;
    retryDelay: number;
    retryDelayMax: number;
    retryDelayMultiplier: number;
    retryDelayJitter: number;
    retryable?: (error: Error) => boolean;
}

Properties:

  • enabled - Enable retrying on write conflict

  • attempts - Maximum retry attempts

  • retryDelay - Initial delay before retrying (ms)

  • retryDelayMax - Maximum delay between attempts (ms)

  • retryDelayMultiplier - Multiply delay after each failed attempt

  • retryDelayJitter - Random offset percentage for delays

  • retryable - Custom predicate deciding whether an error should be retried (default: isRetryableConflict)

Retry is off by default. Passing an options object, or calling .retry() with no arguments, opts a query, mutation, or transaction in. Retrying a non-atomic multi-statement query can apply some statements more than once, so it must always be enabled explicitly.

Example:

// Connection-wide default
await db.connect('ws://localhost:8000', {
    retry: { enabled: true, attempts: 5, retryDelay: 100 }
});

// Per-query override
const [n] = await db
    .query<[number]>('UPDATE counter:c SET n += 1 RETURN n')
    .retry({ attempts: 3 })
    .collect();

SurrealDB version information.

interface VersionInfo {
    version: string;
}

Example:

const info = await db.version();
console.log(info.version); // "surrealdb-2.1.0"

Union type for all authentication methods.

type AnyAuth = SystemAuth | AccessAuth

Union of system-level authentication types.

type SystemAuth = RootAuth | NamespaceAuth | DatabaseAuth

Root-level authentication.

interface RootAuth {
    username: string;
    password: string;
}

Example:

await db.signin({
    username: 'root',
    password: 'root'
});

Namespace-level authentication.

interface NamespaceAuth {
    namespace: string;
    username: string;
    password: string;
}

Example:

await db.signin({
    namespace: 'my_namespace',
    username: 'ns_user',
    password: 'ns_pass'
});

Database-level authentication.

interface DatabaseAuth {
    namespace: string;
    database: string;
    username: string;
    password: string;
}

Example:

await db.signin({
    namespace: 'my_namespace',
    database: 'my_database',
    username: 'db_user',
    password: 'db_pass'
});

Union of access-based authentication types.

type AccessAuth = AccessSystemAuth | AccessBearerAuth | AccessRecordAuth

System access authentication with credentials.

interface AccessSystemAuth {
    namespace: string;
    database: string;
    access: string;
    username: string;
    password: string;
}

Bearer token access authentication.

interface AccessBearerAuth {
    namespace: string;
    database: string;
    access: string;
    token: string;
}

Record user authentication via access methods.

interface AccessRecordAuth {
    namespace: string;
    database: string;
    access: string;
    variables?: Record<string, unknown>;
}

Example:

await db.signup({
    namespace: 'my_namespace',
    database: 'my_database',
    access: 'user_access',
    variables: {
        email: 'user@example.com',
        password: 'password123'
    }
});

A string alias representing an authentication token (JWT).

type Token = string

Authentication token pair.

interface Tokens {
    access: Token;
    refresh?: Token;
}

Example:

const tokens = await db.signin(credentials);
console.log(tokens.access); // JWT access token
console.log(tokens.refresh); // Optional refresh token

Function or static value for providing authentication.

type AuthProvider = 
    | AnyAuth 
    | (() => AnyAuth | Promise<AnyAuth>)

Example:

await db.connect('ws://localhost:8000', {
    authentication: async () => ({
        username: await getUsername(),
        password: await getPassword()
    })
});

Session identifier type.

type Session = Uuid | undefined

Namespace and database pair.

interface NamespaceDatabase {
    namespace?: string;
    database?: string;
}

Example:

await db.use({
    namespace: 'production',
    database: 'main'
});

Events emitted by sessions.

type SessionEvents = {
    auth: [Tokens | null];
    using: [NamespaceDatabase];
}

Events emitted by Surreal instances.

type SurrealEvents = SessionEvents & {
    connecting: [];
    connected: [string];
    reconnecting: [];
    disconnected: [];
    error: [Error];
}

Ensures records have an id field of type RecordId.

type RecordResult<T> = T extends object
    ? { id: RecordId } & T
    : { id: RecordId }

Example:

interface User {
    name: string;
    email: string;
}

const user: RecordResult<User> = await db.select(new RecordId('users', 'john'));
console.log(user.id); // RecordId
console.log(user.name); // string

Response from a query execution.

type QueryResponse<T = unknown> = 
    | QueryResponseSuccess<T> 
    | QueryResponseFailure

interface QueryResponseSuccess<T> {
    success: true;
    stats?: QueryStats;
    type: "live" | "kill" | "other";
    result: T;
}

interface QueryResponseFailure {
    success: false;
    stats?: QueryStats;
    error: {
        code: number;
        message: string;
    };
}

Example:

const responses = await db.query('SELECT * FROM users').responses();

for (const response of responses) {
    if (response.success) {
        console.log('Result:', response.result);
    } else {
        console.error('Error:', response.error.message);
    }
}

Query execution statistics.

interface QueryStats {
    recordsReceived: number;
    bytesReceived: number;
    recordsScanned: number;
    bytesScanned: number;
    duration: Duration;
}

Output format for query results.

type Output = "full" | "diff" | "none"

Represents a mutation event from a live query.

interface Mutation<T = unknown> {
    action: "CREATE" | "UPDATE" | "DELETE";
    result: T;
}

Resources that can be subscribed to with live queries.

type LiveResource = Table

Message received from a live query subscription.

interface LiveMessage<T = unknown> {
    action: "CREATE" | "UPDATE" | "DELETE";
    result: T;
    diff?: unknown;
}

Example:

for await (const message of subscription) {
    console.log(`${message.action}:`, message.result);
}

Valid types for record ID components.

type RecordIdValue = 
    | string 
    | number 
    | Uuid 
    | bigint 
    | unknown[] 
    | Record<string, unknown>

Union type representing any record identifier.

type AnyRecordId = RecordId | RecordIdRange

Extract values from a type, excluding id field.

type Values<T> = Omit<T, 'id'>

Example:

interface User {
    id: RecordId;
    name: string;
    email: string;
}

const userData: Values<User> = {
    name: 'John',
    email: 'john@example.com'
    // id is excluded
};

Make properties nullable.

type Nullable<T> = {
    [K in keyof T]: T[K] | null;
}

Options for value encoding/decoding.

interface CodecOptions {
    useNativeDates?: boolean;
    valueEncodeVisitor?: (value: unknown) => unknown;
    valueDecodeVisitor?: (value: unknown) => unknown;
}

Properties:

  • useNativeDates - Use native Date objects instead of DateTime (loses nanosecond precision)

  • valueEncodeVisitor - Custom function to transform values before encoding

  • valueDecodeVisitor - Custom function to transform values after decoding

Example:

const db = new Surreal({
    codecOptions: {
        useNativeDates: true,
        valueDecodeVisitor: (value) => {
            // Custom transformation
            return value;
        }
    }
});

Options for database export.

interface SqlExportOptions {
    users: boolean;
    accesses: boolean;
    params: boolean;
    functions: boolean;
    analyzers: boolean;
    tables: boolean | string[];
    versions: boolean;
    records: boolean;
    sequences: boolean;
    v3: boolean;
}

The v3 option controls whether to include v3-specific export content.

Example:

const sql = await db.export({
    tables: ['users', 'posts'],
    records: true,
    functions: false
});

Options for exporting a machine learning model.

interface MlExportOptions {
    name: string;
    version: string;
}

Example:

const model = await db.export({
    name: 'prediction-model',
    version: '1.0.0'
});

Expand type for better IDE display.

type Prettify<T> = { [K in keyof T]: T[K] } & {}

Interface for event subscription.

interface EventPublisher<T extends Record<string, unknown[]>> {
    subscribe<K extends keyof T>(
        event: K,
        listener: (...payload: T[K]) => void
    ): () => void;
}

Request options for user-defined API endpoints.

interface ApiRequest<T = unknown> {
    body?: T;
    method?: string;
    headers?: Record<string, string>;
    query?: Record<string, string>;
}

Properties:

  • body - Request body to send

  • method - HTTP method (default: "get")

  • headers - Additional headers for the request

  • query - Query parameters to append to the URL

Example:

const api = db.api();
const result = await api.invoke('/custom', {
    method: 'post',
    body: { data: 'value' },
    headers: { 'X-Custom': 'header' },
    query: { filter: 'active' }
});

Leverage generics for type-safe operations:

interface User {
    name: string;
    email: string;
}

// Type-safe selection
const users = await db.select<User>(new Table('users'));
users[0].name; // TypeScript knows this is a string

Create types for your data models:

interface Post {
    title: string;
    content: string;
    author: RecordId<'users'>;
    created_at: DateTime;
}

const posts = await db.select<Post>(new Table('posts'));

Implement type guards for runtime type checking:

function isUser(value: unknown): value is User {
    return (
        typeof value === 'object' &&
        value !== null &&
        'name' in value &&
        'email' in value
    );
}

if (isUser(data)) {
    console.log(data.email); // Type-safe
}

Properly handle discriminated unions:

const response = await db.query('SELECT * FROM users').responses();

for (const r of response) {
    if (r.success) {
        console.log(r.result); // Success case
    } else {
        console.error(r.error); // Failure case
    }
}

Source: types/

Was this page helpful?