Inferring Types
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>
Inferring Input & Output Types
Let's assume we have this example router:
server.tstsimport {initTRPC } from '@trpc/server';import {z } from "zod";constt =initTRPC .create ();constappRouter =t .router ({post :t .router ({list :t .procedure .query (() => {// imaginary db callreturn [{id : 1,title : 'tRPC is the best!' }];}),byId :t .procedure .input (z .string ()).query ((opts ) => {// imaginary db callreturn {id : 1,title : 'tRPC is the best!' };}),create :t .procedure .input (z .object ({title :z .string (),text :z .string (), })).mutation ((opts ) => {// imaginary db callreturn {id : 1, ...opts .input };}),}),});export typeAppRouter = typeofappRouter ;
server.tstsimport {initTRPC } from '@trpc/server';import {z } from "zod";constt =initTRPC .create ();constappRouter =t .router ({post :t .router ({list :t .procedure .query (() => {// imaginary db callreturn [{id : 1,title : 'tRPC is the best!' }];}),byId :t .procedure .input (z .string ()).query ((opts ) => {// imaginary db callreturn {id : 1,title : 'tRPC is the best!' };}),create :t .procedure .input (z .object ({title :z .string (),text :z .string (), })).mutation ((opts ) => {// imaginary db callreturn {id : 1, ...opts .input };}),}),});export typeAppRouter = typeofappRouter ;
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.tstsimport type { inferRouterInputs, inferRouterOutputs } from '@trpc/server';import type { AppRouter } from './server';type RouterInput = inferRouterInputs<AppRouter>;typeRouterOutput = inferRouterOutputs<AppRouter>; typePostCreateInput = RouterInput['post']['create']; typePostCreateOutput = RouterOutput['post']['create'];
client.tstsimport type { inferRouterInputs, inferRouterOutputs } from '@trpc/server';import type { AppRouter } from './server';type RouterInput = inferRouterInputs<AppRouter>;typeRouterOutput = inferRouterOutputs<AppRouter>; typePostCreateInput = RouterInput['post']['create']; typePostCreateOutput = RouterOutput['post']['create'];
Infer TRPCClientError types
It's also useful to infer the error type for your AppRouter
client.tstsimport { TRPCClientError } from '@trpc/client';import type { AppRouter } from './server';import{ trpc } from './trpc'; exportfunction isTRPCClientError( cause: unknown,): cause isTRPCClientError<AppRouter> { return cause instanceof TRPCClientError; }async function main() {try {await trpc.post.byId.query('1');}catch (cause) { if (isTRPCClientError(cause)) { // `cause` is now typed as your router's `TRPCClientError` console.log('data', cause.data);} else {// [...]}}}main();
client.tstsimport { TRPCClientError } from '@trpc/client';import type { AppRouter } from './server';import{ trpc } from './trpc'; exportfunction isTRPCClientError( cause: unknown,): cause isTRPCClientError<AppRouter> { return cause instanceof TRPCClientError; }async function main() {try {await trpc.post.byId.query('1');}catch (cause) { if (isTRPCClientError(cause)) { // `cause` is now typed as your router's `TRPCClientError` console.log('data', cause.data);} else {// [...]}}}main();