TypeScript Types Reference
Complete reference for Valkeyrie's TypeScript types and interfaces.
Core Types
Key and KeyPart
type KeyPart = Uint8Array | string | number | bigint | boolean | symbol;
type Key = readonly KeyPart[];Keys are arrays of parts. Each part can be one of the allowed types.
Examples:
const key1: Key = ['users', 'alice'];
const key2: Key = ['products', 42, true];
const key3: Key = ['hash', new Uint8Array([1, 2, 3])];Entry and EntryMaybe
interface Entry<T = unknown> {
key: Key;
value: T;
versionstamp: string;
}
type EntryMaybe<T = unknown> =
| Entry<T>
| {
key: Key;
value: null;
versionstamp: null;
}Entry represents an existing database entry. EntryMaybe can represent either an existing entry or a missing key.
Examples:
// Existing entry
const entry: Entry<User> = {
key: ['users', 'alice'],
value: { name: 'Alice' },
versionstamp: '00000000000000000001'
};
// Missing entry
const missing: EntryMaybe<User> = {
key: ['users', 'bob'],
value: null,
versionstamp: null
};Value
type Value = unknown;Values can be any serializable JavaScript type. The exact supported types depend on your chosen serializer.
Operation Types
ListSelector
type ListSelector =
| { prefix: Key }
| { prefix: Key; start: Key }
| { prefix: Key; end: Key }
| { start: Key; end: Key }Defines which entries to list.
Examples:
// List all with prefix
const selector1: ListSelector = { prefix: ['users'] };
// List range within prefix
const selector2: ListSelector = {
prefix: ['users'],
start: ['alice'],
end: ['charlie']
};
// List range without prefix
const selector3: ListSelector = {
start: ['a'],
end: ['z']
};ListOptions
interface ListOptions {
limit?: number;
cursor?: string;
reverse?: boolean;
}Options for list operations.
Example:
const options: ListOptions = {
limit: 10,
reverse: true
};
const entries = db.list({ prefix: ['users'] }, options);SetOptions
interface SetOptions {
expireIn?: number; // milliseconds
}Options for set operations.
Example:
await db.set(['session', 'token'], 'abc123', {
expireIn: 3600000 // 1 hour
});Atomic Operation Types
Check
interface Check {
key: Key;
versionstamp: string | null;
}Version check for optimistic concurrency control.
Example:
const entry = await db.get(['key']);
const check: Check = {
key: ['key'],
versionstamp: entry.versionstamp
};Mutation
type Mutation<T = unknown> = { key: Key } & (
| { type: 'set'; value: T; expireIn?: number }
| { type: 'delete' }
| { type: 'sum'; value: KvU64 }
| { type: 'max'; value: KvU64 }
| { type: 'min'; value: KvU64 }
);Represents a mutation in an atomic operation.
Examples:
const set: Mutation = {
key: ['key'],
type: 'set',
value: 'value',
expireIn: 60000
};
const del: Mutation = {
key: ['key'],
type: 'delete'
};
const sum: Mutation = {
key: ['counter'],
type: 'sum',
value: new KvU64(1n)
};AtomicCheck
interface AtomicCheck {
key: Key;
versionstamp: string | null;
}Same as Check but used in the atomic operation builder.
Factory Method Types
FromOptions
interface FromOptions<T> {
prefix: Key;
keyProperty: keyof T | ((item: T) => KeyPart);
path?: string;
serializer?: () => Serializer;
destroyOnClose?: boolean;
expireIn?: number;
onProgress?: (processed: number, total?: number) => void;
onError?: 'stop' | 'continue';
onErrorCallback?: (error: Error, item: T) => void;
}Options for from() and fromAsync() factory methods.
Example:
const options: FromOptions<User> = {
prefix: ['users'],
keyProperty: 'id',
path: './users.db',
expireIn: 86400000,
onProgress: (processed, total) => {
console.log(`${processed}/${total}`);
},
onError: 'continue',
onErrorCallback: (error, item) => {
console.error('Failed:', item, error);
}
};Serializer Types
Serializer
interface Serializer {
serialize: (value: unknown) => Uint8Array;
deserialize: (value: Uint8Array) => unknown;
}Interface for custom serializers.
Example:
const customSerializer: Serializer = {
serialize: (value) => {
return Buffer.from(JSON.stringify(value), 'utf8');
},
deserialize: (data) => {
return JSON.parse(Buffer.from(data).toString('utf8'));
}
};Schema Validation Types
StandardSchemaV1
// From @standard-schema/spec package
interface StandardSchemaV1 {
readonly '~standard': {
readonly version: 1;
readonly vendor: string;
readonly validate: (value: unknown) => StandardResult<unknown>;
};
}Standard Schema specification interface. Implemented by Zod, Valibot, ArkType, etc.
Type Inference
When using schemas, Valkeyrie automatically infers types:
import { z } from 'zod';
const userSchema = z.object({
name: z.string(),
email: z.string().email(),
age: z.number()
});
const db = await Valkeyrie
.withSchema(['users', '*'], userSchema)
.open();
// Type is automatically inferred!
const user = await db.get(['users', 'alice']);
// user.value: { name: string; email: string; age: number } | null
// Also works for list
for await (const entry of db.list({ prefix: ['users'] })) {
// entry.value: { name: string; email: string; age: number }
console.log(entry.value.email); // ✅ Type-safe
}
// And for watch
const stream = db.watch([['users', 'alice']]);
for await (const [entry] of stream) {
// entry: EntryMaybe<{ name: string; email: string; age: number }>
}Error Types
ValidationError
class ValidationError extends Error {
name: 'ValidationError';
key: Key;
issues: Array<{
message: string;
path: (string | number)[];
}>;
}Thrown when schema validation fails.
Example:
try {
await db.set(['users', 'alice'], invalidData);
} catch (error) {
if (error instanceof ValidationError) {
error.key; // ['users', 'alice']
error.issues; // Array of validation errors
}
}Utility Types
InferTypeForKey
type InferTypeForKey<TRegistry, TKey> = /* internal type */Internal type used for inferring value types based on schema registry and key.
InferTypeForPrefix
type InferTypeForPrefix<TRegistry, TPrefix> = /* internal type */Internal type used for inferring value types based on schema registry and prefix.
Type Guards
Checking Entry Existence
const entry = await db.get(['key']);
if (entry.value !== null) {
// TypeScript knows entry.value is not null
// and entry.versionstamp is string
console.log(entry.value);
console.log(entry.versionstamp);
}Checking Atomic Result
const result = await db.atomic()
.set(['key'], 'value')
.commit();
if (result.ok) {
// TypeScript knows result has versionstamp
console.log(result.versionstamp);
} else {
// result.ok is false - checks failed
}Generic Type Parameters
Valkeyrie<TRegistry>
class Valkeyrie<TRegistry extends SchemaRegistryType = readonly []>The TRegistry type parameter tracks registered schemas for type inference.
Example:
// Without schemas
const db1: Valkeyrie = await Valkeyrie.open();
// With schemas (type is inferred automatically)
const db2 = await Valkeyrie
.withSchema(['users', '*'], userSchema)
.open();
// db2's type includes schema informationBest Practices
1. Use Schema Validation for Auto-Inference
// ✅ Best: Automatic type inference from schemas
const db = await Valkeyrie
.withSchema(['users', '*'], userSchema)
.open();
// Type is automatically inferred - no annotations needed!
const user = await db.get(['users', 'alice']);
// user.value: { name: string; email: string; age: number } | null2. Type Your Data (Without Schemas)
// If not using schemas, provide explicit types
interface User {
name: string;
email: string;
age: number;
}
const entry = await db.get<User>(['users', 'alice']);
// entry.value is User | null3. Const Assertions (Advanced)
// For advanced use cases where you need literal key types
// Note: Not needed for schema type inference
const key = ['users', 'alice'] as const;
// key type: readonly ['users', 'alice']
const key2 = ['users', 'alice'];
// key2 type: string[]4. Handle Null Values
const entry = await db.get(['key']);
// ✅ Good: Check for null
if (entry.value !== null) {
console.log(entry.value);
}
// ✅ Good: Use optional chaining
console.log(entry.value?.someProperty);
// ❌ Bad: Assuming value exists
console.log(entry.value.someProperty); // Type errorSummary
This type reference covers:
- ✅ Core types (Key, Entry, Value)
- ✅ Operation types (ListSelector, SetOptions, etc.)
- ✅ Atomic operation types
- ✅ Factory method types
- ✅ Serializer interface
- ✅ Schema validation types
- ✅ Type inference with schemas
- ✅ Error types
- ✅ Best practices for type safety
For more information:
- API Reference - Method signatures and examples
- Schema Validation Guide - Type inference in action
