TypeScript Types
Generic Parameters
All endpoint helpers accept three generic parameters:
get<TInput, TOutput, TError>(path, handler?, hooks?)
// Same for: post, put, patch, del, endpoint| Parameter | Default | Description |
|---|---|---|
TInput | void (get/del) | Shape of input passed when calling the endpoint |
TOutput | any | Shape of the successful response |
TError | any | Shape of the error response body |
type User = { id: string; name: string; email: string };
type CreateUserInput = { name: string; email: string };
type ApiError = { message: string; code: string };
const createUser = post<CreateUserInput, User, ApiError>('/users');Common Input Patterns
// No input (void)
get<void, User[]>('/users')
// Path parameter
get<{ id: string }, User>((input) => `/users/${input.id}`)
// Query parameters
get<{ page?: number; status?: string }, User[]>((input) => {
const params = new URLSearchParams();
if (input.page) params.set('page', input.page.toString());
if (input.status) params.set('status', input.status);
return `/users?${params}`;
})
// POST body
post<{ name: string; email: string }, User>('/users')
// Partial update
patch<Partial<User> & { id: string }, User>((input) => `/users/${input.id}`)Using TypeScript Utility Types
Avoid duplicating type fields — use built-in utility types:
type User = {
id: string;
name: string;
email: string;
createdAt: string;
};
type CreateUserInput = Omit<User, 'id' | 'createdAt'>; // { name, email }
type UpdateUserInput = Partial<User> & { id: string }; // all optional + required id
type UserSummary = Pick<User, 'id' | 'name'>; // subsetError Types
Use discriminated unions to model endpoints that can return different error kinds:
type ValidationError = { type: 'validation'; errors: Array<{ field: string; message: string }> };
type AuthError = { type: 'auth'; code: 'UNAUTHORIZED' | 'FORBIDDEN' };
type ApiError = ValidationError | AuthError;
try {
await api.createUser(data);
} catch (err: unknown) {
const error = err as { status: number; error: ApiError };
switch (error.error.type) {
case 'validation':
error.error.errors.forEach(e => console.log(`${e.field}: ${e.message}`));
break;
case 'auth':
console.log('Auth error:', error.error.code);
break;
}
}Extracting Types from the Client
type ListUsersResult = Awaited<ReturnType<typeof api.users.list>>;
// → User[]
type GetUserInput = Parameters<typeof api.users.getById>[0];
// → { id: string }