Resource Type Registry
The Resource Type Registry is svadmin’s mechanism for compile-time resource name checking and automatic data type inference. By extending a single TypeScript interface, you get typo-proof resource names and fully-typed data across all hooks.
Quick Setup
Section titled “Quick Setup”1. Define your data types
Section titled “1. Define your data types”export interface Post { id: number; title: string; body: string; status: 'draft' | 'published';}
export interface User { id: number; name: string; email: string;}2. Register in ResourceTypeMap
Section titled “2. Register in ResourceTypeMap”// resource-types.d.ts (or any .ts file)import type { Post, User } from './types';
declare module '@svadmin/core' { interface ResourceTypeMap { posts: Post; users: User; }}3. Enjoy type safety
Section titled “3. Enjoy type safety”// ✅ Compiles — 'posts' is a KnownResources keyuseList({ resource: 'posts' });
// ❌ Compile error — typo caught!useList({ resource: 'postz' });
// ✅ Data is automatically Post[]const query = useList({ resource: 'posts' });query.data?.data[0].title; // string ✓How It Works
Section titled “How It Works”svadmin uses TypeScript declaration merging on an empty interface:
// @svadmin/core exports:export interface ResourceTypeMap {} // empty — users extend itexport type KnownResources = keyof ResourceTypeMap extends never ? string // no registrations → accept any string : Extract<keyof ResourceTypeMap, string>; // registrations exist → constrainexport type InferData<R extends string> = R extends keyof ResourceTypeMap ? ResourceTypeMap[R] : Record<string, unknown>; // unknown resource → base typeKey design: When ResourceTypeMap is empty (no user registrations), KnownResources falls back to string — existing code without registration works unchanged.
Utility Types
Section titled “Utility Types”| Type | Purpose |
|---|---|
ResourceTypeMap | Extend to register resource → data type mappings |
KnownResources | Union of registered resource names (falls back to string) |
InferData<R> | Infer data type for resource R |
BaseRecord | Record<string, unknown> — base for all data types |
With Elysia (Auto-Registration)
Section titled “With Elysia (Auto-Registration)”The @svadmin/elysia package can auto-infer ResourceTypeMap from your Elysia backend:
import type { InferResourceMap } from '@svadmin/elysia';import type { App } from './server';
declare module '@svadmin/core' { interface ResourceTypeMap extends InferResourceMap<App> {}}No manual type registration needed — types are derived directly from your server routes.
Best Practices
Section titled “Best Practices”- Put registrations in a
.d.tsfile — e.g.resource-types.d.tsat your project root - Extend, don’t replace — always use
interface ResourceTypeMap { ... }, nevertype ResourceTypeMap = - One registration per project — all resources go in a single
declare moduleblock - Use with
InferDatain custom hooks and components:
function usePostList() { return useList<InferData<'posts'>>({ resource: 'posts' });}