TypeScript SDKReferenceAPI

Type Helpers

TypeScript helpers for the current hypequery query and serve APIs.

Type Helpers

These are the most useful type helpers in the current initServe / query({ ... }) / serve({ queries }) path.

InferApiType

Use InferApiType to extract the client-safe API shape from an exported api.

import type { InferApiType } from '@hypequery/serve';
import type { api } from '@/analytics/queries';

type Api = InferApiType<typeof api>;

The inferred type maps each query key to:

type Api = {
  activeUsers: {
    input: { limit?: number };
    output: Array<{
      id: string;
      email: string;
      created_at: string;
    }>;
  };
};

This is the type you typically pass into @hypequery/react.

When the API registers metrics or datasets, the inferred type also includes those endpoints: a metric appears under its name, and a dataset under the dataset:<name> key. The same Infer* helpers below work with these keys.

// Metric endpoint input/output.
type RevenueInput = InferQueryInput<typeof api, 'revenue'>;

// Dataset endpoint, keyed as `dataset:<name>`.
type OrdersInput = InferQueryInput<typeof api, 'dataset:orders'>;

InferQueryInput

Extract the input type for one query key from an exported api or query map.

import type { InferQueryInput } from '@hypequery/serve';
import { api } from '@/analytics/queries';

type ActiveUsersInput = InferQueryInput<typeof api, 'activeUsers'>;

InferQueryOutput

Extract the output type for one query key.

import type { InferQueryOutput } from '@hypequery/serve';
import { api } from '@/analytics/queries';

type ActiveUsersOutput = InferQueryOutput<typeof api, 'activeUsers'>;

InferQueryResult

Extract the resolved return type of the query resolver.

import type { InferQueryResult } from '@hypequery/serve';
import { api } from '@/analytics/queries';

type ActiveUsersResult = InferQueryResult<typeof api, 'activeUsers'>;

Query Input / Output Inference

When you define a query with Zod schemas, TypeScript infers both input and output automatically:

const activeUsers = query({
  input: z.object({
    limit: z.number().min(1).max(100).default(10),
  }),
  output: z.array(z.object({
    id: z.string(),
    email: z.string(),
  })),
  query: async ({ ctx, input }) => {
    return ctx.db.table('users').select(['id', 'email']).limit(input.limit).execute();
  },
});

Inside the resolver:

  • input is inferred from input
  • the return value is checked against output

Resolver Types

The runtime also exports resolver/context helpers:

import type { QueryResolverArgs, QueryRuntimeContext } from '@hypequery/serve';
  • QueryResolverArgs<TInput, TContext, TAuth>
  • QueryRuntimeContext<TContext, TAuth>

Query Builder Types

The builder itself remains fully typed from your generated schema:

import { createQueryBuilder } from '@hypequery/clickhouse';
import type { IntrospectedSchema } from './schema';

const db = createQueryBuilder<IntrospectedSchema>({ client });

That gives you:

  • typed table names
  • typed column names
  • typed result shapes
  • typed operators

React Hook Types

InferApiType works directly with createHooks. Import both with import type so the server module stays out of the browser bundle, and take routes from a manifest generated by hypequery generate:manifest analytics/queries.ts:

import { createHooks } from '@hypequery/react';
import type { InferApiType } from '@hypequery/serve';
import type { api } from '@/analytics/queries';
import manifest from '@/analytics/hypequery-manifest.json';

type Api = InferApiType<typeof api>;

export const { useQuery, useMutation } = createHooks<Api>({
  baseUrl: '/api/analytics',
  manifest,
});

For a Python backend or a cloud release, generate the types with hypequery generate:client instead; see React: choose how your hooks get their types.

See Also

On this page

Get early access to hypequery cloud.

Cloud hosts the same model you run in your backend, with a managed API and MCP server, versions, and rollback. We're letting teams in a few at a time. Join the waitlist and we'll reach out when your project can go live.

How do you want to build your analytics layer? (Optional)
What features do you most need? (Optional)

Pick as many as you like.

Only your email is required. All other questions are optional.