Generics

Generic structs and enums produce generic TypeScript interfaces. Type parameters are preserved in procedure signatures, so Paginated<User> in Rust becomes Paginated<User> in TypeScript.

rust
#[derive(Serialize)]
pub struct Paginated<T> {
    pub items: Vec<T>,
    pub total: u64,
    pub page: u32,
}

#[derive(Serialize)]
pub struct User {
    pub id: u64,
    pub name: String,
}

#[rpc_query]
async fn list_users() -> Paginated<User> {
    // ...
}
ts
interface Paginated<T> {
  items: T[];
  total: number;
  page: number;
}

interface User {
  id: number;
  name: string;
}

// list_users returns Paginated<User>

Multiple Type Parameters

Structs with multiple type parameters are supported. All parameters are preserved in the generated TypeScript.

rust
/// Multiple type parameters are preserved as-is.
#[derive(Serialize)]
pub struct ApiResponse<T, E> {
    pub data: Option<T>,
    pub error: Option<E>,
    pub metadata: HashMap<String, String>,
}

#[derive(Serialize)]
pub struct ValidationError {
    pub field: String,
    pub message: String,
}

#[rpc_query]
async fn get_profile(id: u64) -> ApiResponse<User, ValidationError> {
    // ...
}
ts
interface ApiResponse<T, E> {
  data: T | null;
  error: E | null;
  metadata: Record<string, string>;
}

interface ValidationError {
  field: string;
  message: string;
}

// get_profile returns ApiResponse<User, ValidationError>

visit GitHub to learn more about metaxy