Table<T>
The Table class provides type-safe references to database tables, enabling TypeScript type checking for query results.
Import:
import { Table } from 'surrealdb';
Source: value/table.ts
Type Parameters
T - The record type for this table (optional, defaults to string)
Constructor
new Table<T>(name)
Create a new table reference.
Syntax
new Table(name)
new Table<RecordType>(name)
Parameters
| Parameter | Type | Description |
|---|
name required | string | The table name. |
Examples
const users = new Table('users');
interface User {
id: RecordId;
name: string;
email: string;
}
const users = new Table<User>('users');
const allUsers: User[] = await db.select(users);
Properties
name
The table name.
Type: string
const users = new Table('users');
console.log(users.name);
Instance Methods
.toString()
Convert to string representation (escaped table name).
Syntax
table.toString()
Returns
string - Escaped table name
Example
const users = new Table('users');
console.log(users.toString());
const special = new Table('my-table');
console.log(special.toString());
.toJSON()
Serialize for JSON.
Syntax
table.toJSON()
Returns
string - Table name
.equals(other)
Check if two table references are equal.
Syntax
table.equals(other)
Returns
boolean - True if equal
Complete Examples
Type-Safe Queries
import { Surreal, Table } from 'surrealdb';
interface User {
id: RecordId;
name: string;
email: string;
age: number;
}
interface Post {
id: RecordId;
title: string;
content: string;
author: RecordId;
}
const db = new Surreal();
await db.connect('ws://localhost:8000');
const users = new Table<User>('users');
const posts = new Table<Post>('posts');
const allUsers: User[] = await db.select(users);
const allPosts: Post[] = await db.select(posts);
allUsers[0].name;
allUsers[0].title;
Select Operations
const users = new Table<User>('users');
const all = await db.select(users);
const active = await db.select(users)
.where('active = true');
const page = await db.select(users)
.limit(10)
.start(0);
Create Operations
const users = new Table<User>('users');
const user = await db.create(users).content({
name: 'John Doe',
email: 'john@example.com',
age: 30
});
const newUsers = await db.insert(users, [
{ name: 'Alice', email: 'alice@example.com', age: 25 },
{ name: 'Bob', email: 'bob@example.com', age: 35 }
]);
Update Operations
const users = new Table<User>('users');
const updated = await db.update(users)
.merge({ verified: true })
.where('email_confirmed = true');
await db.update(users)
.content({
name: 'New Name',
email: 'new@example.com',
age: 31
})
.where('id = users:john');
Delete Operations
const users = new Table<User>('users');
const deleted = await db.delete(users)
.where('inactive = true');
const deletedWithData = await db.delete(users)
.output('BEFORE')
.where('created_at < $date', {
date: DateTime.parse('2024-01-01')
});
Multiple Tables
interface Product {
id: RecordId;
name: string;
price: Decimal;
}
interface Order {
id: RecordId;
user: RecordId;
products: RecordId[];
total: Decimal;
}
const products = new Table<Product>('products');
const orders = new Table<Order>('orders');
const users = new Table<User>('users');
const [allProducts, allOrders, allUsers] = await Promise.all([
db.select(products),
db.select(orders),
db.select(users)
]);
Query Builder Pattern
const users = new Table<User>('users');
const query = db.select(users)
.fields('name', 'email', 'age')
.where('age >= $minAge', { minAge: 18 })
.order('name ASC')
.limit(100);
const results = await query;
Live Queries
const users = new Table<User>('users');
const subscription = await db.live(users);
for await (const update of subscription) {
if (update.action === 'CREATE') {
console.log('New user:', update.result);
} else if (update.action === 'UPDATE') {
console.log('User updated:', update.result);
} else if (update.action === 'DELETE') {
console.log('User deleted:', update.result);
}
}
await subscription.kill();
Transactions
const users = new Table<User>('users');
const orders = new Table<Order>('orders');
const txn = await db.beginTransaction();
try {
const user = await txn.create(users).content({
name: 'Jane Doe',
email: 'jane@example.com'
});
await txn.create(orders).content({
user: user.id,
products: [],
total: new Decimal('0')
});
await txn.commit();
} catch (error) {
await txn.cancel();
}
Generic Table Functions
async function getAllFromTable<T>(
db: Surreal,
table: Table<T>
): Promise<T[]> {
return db.select(table);
}
async function deleteAllFromTable<T>(
db: Surreal,
table: Table<T>
): Promise<T[]> {
return db.delete(table);
}
const users = await getAllFromTable(db, new Table<User>('users'));
const posts = await getAllFromTable(db, new Table<Post>('posts'));
Table Schema Validation
interface StrictUser {
id: RecordId<'users', string>;
name: string;
email: string;
age: number;
created_at: DateTime;
updated_at: DateTime;
}
const users = new Table<StrictUser>('users');
const user = await db.create(users).content({
name: 'Alice',
email: 'alice@example.com',
age: 25,
created_at: DateTime.now(),
updated_at: DateTime.now()
});
Repository Pattern
class UserRepository {
private table = new Table<User>('users');
constructor(private db: Surreal) {}
async getAll(): Promise<User[]> {
return this.db.select(this.table);
}
async getById(id: RecordId): Promise<User | undefined> {
return this.db.select(id);
}
async create(data: Omit<User, 'id'>): Promise<User> {
return this.db.create(this.table).content(data);
}
async update(id: RecordId, data: Partial<User>): Promise<User> {
return this.db.update(id).merge(data);
}
async delete(id: RecordId): Promise<void> {
await this.db.delete(id);
}
async findByEmail(email: string): Promise<User[]> {
return this.db.select(this.table)
.where('email = $email', { email });
}
}
const userRepo = new UserRepository(db);
const users = await userRepo.getAll();
const john = await userRepo.findByEmail('john@example.com');
Best Practices
1. Use Type Parameters
const users = new Table<User>('users');
const results: User[] = await db.select(users);
const users = new Table('users');
const results = await db.select(users);
2. Define Interfaces for Tables
interface User {
id: RecordId;
name: string;
email: string;
created_at: DateTime;
}
const users = new Table<User>('users');
const users = new Table('users');
3. Reuse Table References
const USERS_TABLE = new Table<User>('users');
async function getUsers() {
return db.select(USERS_TABLE);
}
async function createUser(data: Omit<User, 'id'>) {
return db.create(USERS_TABLE).content(data);
}
async function getUsers() {
return db.select(new Table('users'));
}
4. Use with RecordId for Type Safety
interface User {
id: RecordId<'users', string>;
name: string;
}
const users = new Table<User>('users');
const userId: RecordId<'users', string> = new RecordId('users', 'john');
Common Patterns
Enum-based Tables
enum Tables {
Users = 'users',
Posts = 'posts',
Comments = 'comments'
}
const users = new Table<User>(Tables.Users);
const posts = new Table<Post>(Tables.Posts);
Table Factory
function createTable<T>(name: string): Table<T> {
return new Table<T>(name);
}
const users = createTable<User>('users');
const posts = createTable<Post>('posts');
See Also