Inferring Types
On this page
It is often useful to access the types of your API within your clients. For this purpose, you are able to infer the types contained in your AppRouter.
@trpc/server exports the following helper types to assist with inferring these types from the AppRouter exported by your @trpc/server router:
inferRouterInputs<TRouter>inferRouterOutputs<TRouter>inferProcedureInput<TProcedure>inferProcedureOutput<TProcedure>inferSubscriptionInput<TProcedure>inferSubscriptionOutput<TProcedure>
Inferring Input & Output Types
Let's assume we have this example router:
server.ts
import { const initTRPC: TRPCBuilder<object, object>initTRPC } from '@trpc/server';
import { import zz } from "zod";
const const t: TRPCRootObject<object, object, RuntimeConfigOptions<object, object>, {
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}>
t = const initTRPC: TRPCBuilder<object, object>initTRPC.TRPCBuilder<object, object>.create<RuntimeConfigOptions<object, object>>(opts?: RuntimeConfigOptions<object, object> | undefined): TRPCRootObject<object, object, RuntimeConfigOptions<object, object>, {
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}>
create();
const const appRouter: BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
post: BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
list: QueryProcedure<{
input: void;
output: {
id: number;
title: string;
}[];
meta: object;
errorShape: DefaultErrorShape;
}>;
byId: QueryProcedure<{
input: string;
output: {
id: number;
title: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
create: MutationProcedure<{
input: {
title: string;
text: string;
};
output: {
...;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
onPostAdd: SubscriptionProcedure<...>;
}>>;
}>>
appRouter = const t: TRPCRootObject<object, object, RuntimeConfigOptions<object, object>, {
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}>
t.TRPCRootObject<object, object, RuntimeConfigOptions<object, object>, { ctx: object; meta: object; errorShape: DefaultErrorShape; transformer: false; }>.router: RouterBuilder
<{
post: BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
list: QueryProcedure<{
input: void;
output: {
id: number;
title: string;
}[];
meta: object;
errorShape: DefaultErrorShape;
}>;
byId: QueryProcedure<{
input: string;
output: {
id: number;
title: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
create: MutationProcedure<{
input: {
title: string;
text: string;
};
output: {
title: string;
text: string;
id: number;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
onPostAdd: SubscriptionProcedure<...>;
}>>;
}>(_: {
post: BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
list: QueryProcedure<{
input: void;
output: {
id: number;
title: string;
}[];
meta: object;
errorShape: DefaultErrorShape;
}>;
byId: QueryProcedure<{
input: string;
output: {
id: number;
title: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
create: MutationProcedure<{
input: {
title: string;
text: string;
};
output: {
title: string;
text: string;
id: number;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
onPostAdd: SubscriptionProcedure<...>;
}>>;
}) => BuiltRouter<...>
router({
post: BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
list: QueryProcedure<{
input: void;
output: {
id: number;
title: string;
}[];
meta: object;
errorShape: DefaultErrorShape;
}>;
byId: QueryProcedure<{
input: string;
output: {
id: number;
title: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
create: MutationProcedure<{
input: {
title: string;
text: string;
};
output: {
...;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
onPostAdd: SubscriptionProcedure<...>;
}>>
post: const t: TRPCRootObject<object, object, RuntimeConfigOptions<object, object>, {
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}>
t.TRPCRootObject<object, object, RuntimeConfigOptions<object, object>, { ctx: object; meta: object; errorShape: DefaultErrorShape; transformer: false; }>.router: RouterBuilder
<{
list: QueryProcedure<{
input: void;
output: {
id: number;
title: string;
}[];
meta: object;
errorShape: DefaultErrorShape;
}>;
byId: QueryProcedure<{
input: string;
output: {
id: number;
title: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
create: MutationProcedure<{
input: {
title: string;
text: string;
};
output: {
title: string;
text: string;
id: number;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
onPostAdd: SubscriptionProcedure<{
input: {
authorId: string;
};
output: AsyncIterable<{
id: number;
title: string;
authorId: string;
}, void, any>;
meta: object;
errorShape: DefaultErrorShape;
}>;
}>(_: {
list: QueryProcedure<{
input: void;
output: {
id: number;
title: string;
}[];
meta: object;
errorShape: DefaultErrorShape;
}>;
byId: QueryProcedure<{
input: string;
output: {
id: number;
title: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
create: MutationProcedure<{
input: {
title: string;
text: string;
};
output: {
title: string;
text: string;
id: number;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
onPostAdd: SubscriptionProcedure<{
input: {
authorId: string;
};
output: AsyncIterable<{
id: number;
title: string;
authorId: string;
}, void, any>;
meta: object;
errorShape: DefaultErrorShape;
}>;
}) => BuiltRouter<...>
router({
list: QueryProcedure<{
input: void;
output: {
id: number;
title: string;
}[];
meta: object;
errorShape: DefaultErrorShape;
}>
list: const t: TRPCRootObject<object, object, RuntimeConfigOptions<object, object>, {
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}>
t.TRPCRootObject<object, object, RuntimeConfigOptions<object, object>, { ctx: object; meta: object; errorShape: DefaultErrorShape; transformer: false; }>.procedure: ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>procedure
.ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>.query<{
id: number;
title: string;
}[]>(resolver: ProcedureResolver<object, object, object, UnsetMarker, UnsetMarker, {
id: number;
title: string;
}[]>): QueryProcedure<{
input: void;
output: {
id: number;
title: string;
}[];
meta: object;
errorShape: DefaultErrorShape;
}>
query(() => {
// imaginary db call
return [{ id: numberid: 1, title: stringtitle: 'tRPC is the best!' }];
}),
byId: QueryProcedure<{
input: string;
output: {
id: number;
title: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>
byId: const t: TRPCRootObject<object, object, RuntimeConfigOptions<object, object>, {
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}>
t.TRPCRootObject<object, object, RuntimeConfigOptions<object, object>, { ctx: object; meta: object; errorShape: DefaultErrorShape; transformer: false; }>.procedure: ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>procedure
.ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>.input<z.ZodString>(schema: z.ZodString): ProcedureBuilder<object, object, object, string, string, UnsetMarker, UnsetMarker, false, DefaultErrorShape>input(import zz.function string(params?: string | z.core.$ZodStringParams): z.ZodString (+1 overload)string())
.ProcedureBuilder<object, object, object, string, string, UnsetMarker, UnsetMarker, false, DefaultErrorShape>.query<{
id: number;
title: string;
}>(resolver: ProcedureResolver<object, object, object, string, UnsetMarker, {
id: number;
title: string;
}>): QueryProcedure<{
input: string;
output: {
id: number;
title: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>
query((opts: ProcedureResolverOptions<object, object, object, string>opts) => {
// imaginary db call
return { id: numberid: 1, title: stringtitle: 'tRPC is the best!' };
}),
create: MutationProcedure<{
input: {
title: string;
text: string;
};
output: {
...;
};
meta: object;
errorShape: DefaultErrorShape;
}>
create: const t: TRPCRootObject<object, object, RuntimeConfigOptions<object, object>, {
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}>
t.TRPCRootObject<object, object, RuntimeConfigOptions<object, object>, { ctx: object; meta: object; errorShape: DefaultErrorShape; transformer: false; }>.procedure: ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>procedure
.ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>.input<z.ZodObject<{
title: z.ZodString;
text: z.ZodString;
}, z.core.$strip>>(schema: z.ZodObject<{
title: z.ZodString;
text: z.ZodString;
}, z.core.$strip>): ProcedureBuilder<object, object, object, {
title: string;
text: string;
}, {
title: string;
text: string;
}, UnsetMarker, UnsetMarker, false, DefaultErrorShape>
input(import zz.function object<{
title: z.ZodString;
text: z.ZodString;
}>(shape?: {
title: z.ZodString;
text: z.ZodString;
} | undefined, params?: string | {
error?: string | z.core.$ZodErrorMap<NonNullable<z.core.$ZodIssueUnrecognizedKeys | z.core.$ZodIssueInvalidType<unknown>>> | undefined;
message?: string | undefined | undefined;
} | undefined): z.ZodObject<{
title: z.ZodString;
text: z.ZodString;
}, z.core.$strip>
object({ title: z.ZodStringtitle: import zz.function string(params?: string | z.core.$ZodStringParams): z.ZodString (+1 overload)string(), text: z.ZodStringtext: import zz.function string(params?: string | z.core.$ZodStringParams): z.ZodString (+1 overload)string(), }))
.ProcedureBuilder<object, object, object, { title: string; text: string; }, { title: string; text: string; }, UnsetMarker, UnsetMarker, false, DefaultErrorShape>.mutation<{
title: string;
text: string;
id: number;
}>(resolver: ProcedureResolver<object, object, object, {
title: string;
text: string;
}, UnsetMarker, {
title: string;
text: string;
id: number;
}>): MutationProcedure<{
input: {
title: string;
text: string;
};
output: {
title: string;
text: string;
id: number;
};
meta: object;
errorShape: DefaultErrorShape;
}>
mutation((opts: ProcedureResolverOptions<object, object, object, {
title: string;
text: string;
}>
opts) => {
// imaginary db call
return { id: numberid: 1, ...opts: ProcedureResolverOptions<object, object, object, {
title: string;
text: string;
}>
opts.ProcedureResolverOptions<object, object, object, { title: string; text: string; }>.input: {
title: string;
text: string;
}
input };
}),
onPostAdd: SubscriptionProcedure<{
input: {
authorId: string;
};
output: AsyncIterable<{
id: number;
title: string;
authorId: string;
}, void, any>;
meta: object;
errorShape: DefaultErrorShape;
}>
onPostAdd: const t: TRPCRootObject<object, object, RuntimeConfigOptions<object, object>, {
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}>
t.TRPCRootObject<object, object, RuntimeConfigOptions<object, object>, { ctx: object; meta: object; errorShape: DefaultErrorShape; transformer: false; }>.procedure: ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>procedure
.ProcedureBuilder<object, object, object, UnsetMarker, UnsetMarker, UnsetMarker, UnsetMarker, false, DefaultErrorShape>.input<z.ZodObject<{
authorId: z.ZodString;
}, z.core.$strip>>(schema: z.ZodObject<{
authorId: z.ZodString;
}, z.core.$strip>): ProcedureBuilder<object, object, object, {
authorId: string;
}, {
authorId: string;
}, UnsetMarker, UnsetMarker, false, DefaultErrorShape>
input(import zz.function object<{
authorId: z.ZodString;
}>(shape?: {
authorId: z.ZodString;
} | undefined, params?: string | {
error?: string | z.core.$ZodErrorMap<NonNullable<z.core.$ZodIssueUnrecognizedKeys | z.core.$ZodIssueInvalidType<unknown>>> | undefined;
message?: string | undefined | undefined;
} | undefined): z.ZodObject<{
authorId: z.ZodString;
}, z.core.$strip>
object({ authorId: z.ZodStringauthorId: import zz.function string(params?: string | z.core.$ZodStringParams): z.ZodString (+1 overload)string() }))
.ProcedureBuilder<object, object, object, { authorId: string; }, { authorId: string; }, UnsetMarker, UnsetMarker, false, DefaultErrorShape>.subscription<AsyncGenerator<{
id: number;
title: string;
authorId: string;
}, void, any>>(resolver: ProcedureResolver<object, object, object, {
authorId: string;
}, UnsetMarker, AsyncGenerator<{
id: number;
title: string;
authorId: string;
}, void, any>>): SubscriptionProcedure<{
input: {
authorId: string;
};
output: AsyncIterable<{
id: number;
title: string;
authorId: string;
}, void, any>;
meta: object;
errorShape: DefaultErrorShape;
}> (+1 overload)
subscription(async function* ({ input: {
authorId: string;
}
input }) {
// imaginary event source
yield {
id: numberid: 1,
title: stringtitle: 'tRPC is the best!',
authorId: stringauthorId: input: {
authorId: string;
}
input.authorId: stringauthorId,
};
}),
}),
});
export type type AppRouter = Router<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
post: BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
list: QueryProcedure<{
input: void;
output: {
id: number;
title: string;
}[];
meta: object;
errorShape: DefaultErrorShape;
}>;
byId: QueryProcedure<{
input: string;
output: {
id: number;
title: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
create: MutationProcedure<{
input: {
title: string;
text: string;
};
output: {
...;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
onPostAdd: SubscriptionProcedure<...>;
}>>;
}>> & DecorateCreateRouterOptions<...>
AppRouter = typeof const appRouter: BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
post: BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
list: QueryProcedure<{
input: void;
output: {
id: number;
title: string;
}[];
meta: object;
errorShape: DefaultErrorShape;
}>;
byId: QueryProcedure<{
input: string;
output: {
id: number;
title: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
create: MutationProcedure<{
input: {
title: string;
text: string;
};
output: {
...;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
onPostAdd: SubscriptionProcedure<...>;
}>>;
}>>
appRouter;Using the helpers, we can infer the types of our router. The following example shows how to infer the types of the post.create procedure:
client.ts
import type { type inferRouterInputs<TRouter extends AnyRouter> = { [TKey in keyof TRouter["_def"]["record"]]: TRouter["_def"]["record"][TKey] extends infer $Value ? $Value extends AnyProcedure ? inferProcedureInput<$Value> : $Value extends RouterRecord ? GetInferenceHelpers<"input", TRouter["_def"]["_config"]["$types"], $Value> : never : never; }inferRouterInputs, type inferRouterOutputs<TRouter extends AnyRouter> = { [TKey in keyof TRouter["_def"]["record"]]: TRouter["_def"]["record"][TKey] extends infer $Value ? $Value extends AnyProcedure ? inferTransformedProcedureOutput<TRouter["_def"]["_config"]["$types"], $Value> : $Value extends RouterRecord ? GetInferenceHelpers<"output", TRouter["_def"]["_config"]["$types"], $Value> : never : never; }inferRouterOutputs } from '@trpc/server';
import type { type AppRouter = Router<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
post: BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
list: QueryProcedure<{
input: void;
output: {
id: number;
title: string;
}[];
meta: object;
errorShape: DefaultErrorShape;
}>;
byId: QueryProcedure<{
input: string;
output: {
id: number;
title: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
create: MutationProcedure<{
input: {
title: string;
text: string;
};
output: {
...;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
onPostAdd: SubscriptionProcedure<...>;
}>>;
}>> & DecorateCreateRouterOptions<...>
AppRouter } from './server';
type type RouterInput = {
post: GetInferenceHelpers<"input", {
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
list: QueryProcedure<{
input: void;
output: {
id: number;
title: string;
}[];
meta: object;
errorShape: DefaultErrorShape;
}>;
byId: QueryProcedure<{
input: string;
output: {
id: number;
title: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
create: MutationProcedure<{
input: {
title: string;
text: string;
};
output: {
...;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
onPostAdd: SubscriptionProcedure<...>;
}>>;
}
RouterInput = type inferRouterInputs<TRouter extends AnyRouter> = { [TKey in keyof TRouter["_def"]["record"]]: TRouter["_def"]["record"][TKey] extends infer $Value ? $Value extends AnyProcedure ? inferProcedureInput<$Value> : $Value extends RouterRecord ? GetInferenceHelpers<"input", TRouter["_def"]["_config"]["$types"], $Value> : never : never; }inferRouterInputs<type AppRouter = Router<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
post: BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
list: QueryProcedure<{
input: void;
output: {
id: number;
title: string;
}[];
meta: object;
errorShape: DefaultErrorShape;
}>;
byId: QueryProcedure<{
input: string;
output: {
id: number;
title: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
create: MutationProcedure<{
input: {
title: string;
text: string;
};
output: {
...;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
onPostAdd: SubscriptionProcedure<...>;
}>>;
}>> & DecorateCreateRouterOptions<...>
AppRouter>;
type type RouterOutput = {
post: GetInferenceHelpers<"output", {
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
list: QueryProcedure<{
input: void;
output: {
id: number;
title: string;
}[];
meta: object;
errorShape: DefaultErrorShape;
}>;
byId: QueryProcedure<{
input: string;
output: {
id: number;
title: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
create: MutationProcedure<{
input: {
title: string;
text: string;
};
output: {
...;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
onPostAdd: SubscriptionProcedure<...>;
}>>;
}
RouterOutput = type inferRouterOutputs<TRouter extends AnyRouter> = { [TKey in keyof TRouter["_def"]["record"]]: TRouter["_def"]["record"][TKey] extends infer $Value ? $Value extends AnyProcedure ? inferTransformedProcedureOutput<TRouter["_def"]["_config"]["$types"], $Value> : $Value extends RouterRecord ? GetInferenceHelpers<"output", TRouter["_def"]["_config"]["$types"], $Value> : never : never; }inferRouterOutputs<type AppRouter = Router<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
post: BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
list: QueryProcedure<{
input: void;
output: {
id: number;
title: string;
}[];
meta: object;
errorShape: DefaultErrorShape;
}>;
byId: QueryProcedure<{
input: string;
output: {
id: number;
title: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
create: MutationProcedure<{
input: {
title: string;
text: string;
};
output: {
...;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
onPostAdd: SubscriptionProcedure<...>;
}>>;
}>> & DecorateCreateRouterOptions<...>
AppRouter>;
type PostCreateInput = type RouterInput = {
post: GetInferenceHelpers<"input", {
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
list: QueryProcedure<{
input: void;
output: {
id: number;
title: string;
}[];
meta: object;
errorShape: DefaultErrorShape;
}>;
byId: QueryProcedure<{
input: string;
output: {
id: number;
title: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
create: MutationProcedure<{
input: {
title: string;
text: string;
};
output: {
...;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
onPostAdd: SubscriptionProcedure<...>;
}>>;
}
RouterInput['post']['create'];type PostCreateOutput = type RouterOutput = {
post: GetInferenceHelpers<"output", {
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
list: QueryProcedure<{
input: void;
output: {
id: number;
title: string;
}[];
meta: object;
errorShape: DefaultErrorShape;
}>;
byId: QueryProcedure<{
input: string;
output: {
id: number;
title: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
create: MutationProcedure<{
input: {
title: string;
text: string;
};
output: {
...;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
onPostAdd: SubscriptionProcedure<...>;
}>>;
}
RouterOutput['post']['create'];Inferring Individual Procedure Types
If you already have access to a specific procedure on your router, you can infer its input or output directly:
client.ts
import type {
type inferProcedureInput<TProcedure extends AnyProcedure> = undefined extends inferProcedureParams<TProcedure>["$types"]["input"] ? void | inferProcedureParams<TProcedure>["$types"]["input"] : inferProcedureParams<TProcedure>["$types"]["input"]inferProcedureInput,
type inferProcedureOutput<TProcedure> = inferProcedureParams<TProcedure>["$types"]["output"]inferProcedureOutput,
} from '@trpc/server';
import type { type AppRouter = Router<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
post: BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
list: QueryProcedure<{
input: void;
output: {
id: number;
title: string;
}[];
meta: object;
errorShape: DefaultErrorShape;
}>;
byId: QueryProcedure<{
input: string;
output: {
id: number;
title: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
create: MutationProcedure<{
input: {
title: string;
text: string;
};
output: {
...;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
onPostAdd: SubscriptionProcedure<...>;
}>>;
}>> & DecorateCreateRouterOptions<...>
AppRouter } from './server';
type PostByIdInput = type inferProcedureInput<TProcedure extends AnyProcedure> = undefined extends inferProcedureParams<TProcedure>["$types"]["input"] ? void | inferProcedureParams<TProcedure>["$types"]["input"] : inferProcedureParams<TProcedure>["$types"]["input"]inferProcedureInput<type AppRouter = Router<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
post: BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
list: QueryProcedure<{
input: void;
output: {
id: number;
title: string;
}[];
meta: object;
errorShape: DefaultErrorShape;
}>;
byId: QueryProcedure<{
input: string;
output: {
id: number;
title: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
create: MutationProcedure<{
input: {
title: string;
text: string;
};
output: {
...;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
onPostAdd: SubscriptionProcedure<...>;
}>>;
}>> & DecorateCreateRouterOptions<...>
AppRouter['post']['byId']>;type PostByIdOutput = type inferProcedureOutput<TProcedure> = inferProcedureParams<TProcedure>["$types"]["output"]inferProcedureOutput<type AppRouter = Router<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
post: BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
list: QueryProcedure<{
input: void;
output: {
id: number;
title: string;
}[];
meta: object;
errorShape: DefaultErrorShape;
}>;
byId: QueryProcedure<{
input: string;
output: {
id: number;
title: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
create: MutationProcedure<{
input: {
title: string;
text: string;
};
output: {
...;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
onPostAdd: SubscriptionProcedure<...>;
}>>;
}>> & DecorateCreateRouterOptions<...>
AppRouter['post']['byId']>;For subscriptions, you can infer the subscription input and the emitted data type:
client.ts
import type {
type inferSubscriptionInput<TProcedure extends AnySubscriptionProcedure> = undefined extends inferProcedureParams<TProcedure>["$types"]["input"] ? void | inferProcedureParams<TProcedure>["$types"]["input"] : inferProcedureParams<TProcedure>["$types"]["input"]inferSubscriptionInput,
type inferSubscriptionOutput<TProcedure extends AnySubscriptionProcedure> = TProcedure extends LegacyObservableSubscriptionProcedure<any> ? inferProcedureOutput<TProcedure> : inferAsyncIterableYield<inferProcedureOutput<TProcedure>>inferSubscriptionOutput,
} from '@trpc/server';
import type { type AppRouter = Router<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
post: BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
list: QueryProcedure<{
input: void;
output: {
id: number;
title: string;
}[];
meta: object;
errorShape: DefaultErrorShape;
}>;
byId: QueryProcedure<{
input: string;
output: {
id: number;
title: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
create: MutationProcedure<{
input: {
title: string;
text: string;
};
output: {
...;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
onPostAdd: SubscriptionProcedure<...>;
}>>;
}>> & DecorateCreateRouterOptions<...>
AppRouter } from './server';
type OnPostAddInput = type inferSubscriptionInput<TProcedure extends AnySubscriptionProcedure> = undefined extends inferProcedureParams<TProcedure>["$types"]["input"] ? void | inferProcedureParams<TProcedure>["$types"]["input"] : inferProcedureParams<TProcedure>["$types"]["input"]inferSubscriptionInput<type AppRouter = Router<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
post: BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
list: QueryProcedure<{
input: void;
output: {
id: number;
title: string;
}[];
meta: object;
errorShape: DefaultErrorShape;
}>;
byId: QueryProcedure<{
input: string;
output: {
id: number;
title: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
create: MutationProcedure<{
input: {
title: string;
text: string;
};
output: {
...;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
onPostAdd: SubscriptionProcedure<...>;
}>>;
}>> & DecorateCreateRouterOptions<...>
AppRouter['post']['onPostAdd']>;type OnPostAddOutput = type inferSubscriptionOutput<TProcedure extends AnySubscriptionProcedure> = TProcedure extends LegacyObservableSubscriptionProcedure<any> ? inferProcedureOutput<TProcedure> : inferAsyncIterableYield<inferProcedureOutput<TProcedure>>inferSubscriptionOutput<type AppRouter = Router<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
post: BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
list: QueryProcedure<{
input: void;
output: {
id: number;
title: string;
}[];
meta: object;
errorShape: DefaultErrorShape;
}>;
byId: QueryProcedure<{
input: string;
output: {
id: number;
title: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
create: MutationProcedure<{
input: {
title: string;
text: string;
};
output: {
...;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
onPostAdd: SubscriptionProcedure<...>;
}>>;
}>> & DecorateCreateRouterOptions<...>
AppRouter['post']['onPostAdd']>;Infer TRPCClientError types
It's also useful to infer the error type for your AppRouter
client.ts
import { class TRPCClientError<TRouterOrProcedure extends InferrableClientTypes>TRPCClientError } from '@trpc/client';
import type { type AppRouter = Router<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
post: BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
list: QueryProcedure<{
input: void;
output: {
id: number;
title: string;
}[];
meta: object;
errorShape: DefaultErrorShape;
}>;
byId: QueryProcedure<{
input: string;
output: {
id: number;
title: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
create: MutationProcedure<{
input: {
title: string;
text: string;
};
output: {
...;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
onPostAdd: SubscriptionProcedure<...>;
}>>;
}>> & DecorateCreateRouterOptions<...>
AppRouter } from './server';
import { const trpc: TRPCClient<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
post: BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
list: QueryProcedure<{
input: void;
output: {
id: number;
title: string;
}[];
meta: object;
errorShape: DefaultErrorShape;
}>;
byId: QueryProcedure<{
input: string;
output: {
id: number;
title: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
create: MutationProcedure<{
input: {
title: string;
text: string;
};
output: {
...;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
onPostAdd: SubscriptionProcedure<...>;
}>>;
}>>>
trpc } from './trpc';
export function function isTRPCClientError(cause: unknown): cause is TRPCClientError<AppRouter>isTRPCClientError(
cause: unknowncause: unknown,
): cause: unknowncause is class TRPCClientError<TRouterOrProcedure extends InferrableClientTypes>TRPCClientError<type AppRouter = Router<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
post: BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
list: QueryProcedure<{
input: void;
output: {
id: number;
title: string;
}[];
meta: object;
errorShape: DefaultErrorShape;
}>;
byId: QueryProcedure<{
input: string;
output: {
id: number;
title: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
create: MutationProcedure<{
input: {
title: string;
text: string;
};
output: {
...;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
onPostAdd: SubscriptionProcedure<...>;
}>>;
}>> & DecorateCreateRouterOptions<...>
AppRouter> {
return cause: unknowncause instanceof class TRPCClientError<TRouterOrProcedure extends InferrableClientTypes>TRPCClientError;
}
async function function main(): Promise<void>main() {
try {
await const trpc: TRPCClient<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
post: BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
list: QueryProcedure<{
input: void;
output: {
id: number;
title: string;
}[];
meta: object;
errorShape: DefaultErrorShape;
}>;
byId: QueryProcedure<{
input: string;
output: {
id: number;
title: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
create: MutationProcedure<{
input: {
title: string;
text: string;
};
output: {
...;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
onPostAdd: SubscriptionProcedure<...>;
}>>;
}>>>
trpc.post: DecoratedProcedureRecord<{
transformer: false;
errorShape: DefaultErrorShape;
}, DecorateCreateRouterOptions<{
list: QueryProcedure<{
input: void;
output: {
id: number;
title: string;
}[];
meta: object;
errorShape: DefaultErrorShape;
}>;
byId: QueryProcedure<{
input: string;
output: {
id: number;
title: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
create: MutationProcedure<{
input: {
title: string;
text: string;
};
output: {
...;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
onPostAdd: SubscriptionProcedure<...>;
}>>
post.byId: {
query: Resolver<{
input: string;
output: {
id: number;
title: string;
};
errorShape: DefaultErrorShape;
transformer: false;
}>;
}
byId.query: (input: string, opts?: TRPCProcedureOptions) => TRPCTaggedPromise<{
id: number;
title: string;
}, DefaultErrorShape>
query('1');
} catch (function (local var) cause: unknowncause) {
if (function isTRPCClientError(cause: unknown): cause is TRPCClientError<AppRouter>isTRPCClientError(function (local var) cause: unknowncause)) {
// `cause` is now typed as your router's `TRPCClientError`
var console: Consoleconsole.Console.log(...data: any[]): voidlog('data', function (local var) cause: TRPCClientError<BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
post: BuiltRouter<{
ctx: object;
meta: object;
errorShape: DefaultErrorShape;
transformer: false;
}, DecorateCreateRouterOptions<{
list: QueryProcedure<{
input: void;
output: {
id: number;
title: string;
}[];
meta: object;
errorShape: DefaultErrorShape;
}>;
byId: QueryProcedure<{
input: string;
output: {
id: number;
title: string;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
create: MutationProcedure<{
input: {
title: string;
text: string;
};
output: {
...;
};
meta: object;
errorShape: DefaultErrorShape;
}>;
onPostAdd: SubscriptionProcedure<...>;
}>>;
}>>>
cause.data); } else {
// [...]
}
}
}
function main(): Promise<void>main();