TypeScript Types

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

Connection Types

ConnectionStatus

Represents the current connection state.

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

Example:

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

DriverOptions

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
}
});

ConnectOptions

Options for establishing a connection.

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

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)

Example:

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

ReconnectOptions

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

VersionInfo

SurrealDB version information.

interface VersionInfo {
version: string;
}

Example:

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

Authentication Types

AnyAuth

Union type for all authentication methods.

type AnyAuth = 
| SystemAuth
| NamespaceAuth
| DatabaseAuth
| AccessRecordAuth

SystemAuth

System user authentication (root, namespace, or database level).

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

Example:

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

AccessRecordAuth

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'
}
});

Tokens

Authentication token pair.

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

Example:

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

AuthProvider

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 Types

Session

Session identifier type.

type Session = Uuid | undefined

NamespaceDatabase

Namespace and database pair.

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

Example:

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

SessionEvents

Events emitted by sessions.

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

SurrealEvents

Events emitted by Surreal instances.

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

Query Types

RecordResult<T>

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

QueryResponse<T>

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);
}
}

QueryStats

Query execution statistics.

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

LiveResource

Resources that can be subscribed to with live queries.

type LiveResource = Table | RecordId | RecordIdRange

LiveMessage

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);
}

Value Types

RecordIdValue

Valid types for record ID components.

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

Values<T>

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
};

Nullable<T>

Make properties nullable.

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

Codec Types

CodecOptions

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;
}
}
});

Export/Import Types

SqlExportOptions

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
});

Utility Types

Prettify<T>

Expand type for better IDE display.

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

EventPublisher<T>

Interface for event subscription.

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

ApiRequest<T>

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' }
});

Best Practices

1. Use Generic Type Parameters

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

2. Define Custom Types

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'));

3. Use Type Guards

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
}

4. Handle Union Types

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
}
}

See Also

Source: types/