Inférence de types
Cette page a été traduite par PageTurner AI (bêta). Non approuvée officiellement par le projet. Vous avez trouvé une erreur ? Signaler un problème →
En complément de l'inférence de types offerte par @trpc/server (voir ici), cette intégration propose également des utilitaires d'inférence spécifiquement conçus pour React.
Inférer les options de React Query à partir de votre routeur
Lorsque vous créez des hooks personnalisés autour des procédures tRPC, il est parfois nécessaire d'inférer automatiquement les types des options à partir du routeur. Vous pouvez y parvenir via l'utilitaire inferReactQueryProcedureOptions exporté par @trpc/react-query.
trpc.tstsimport {createTRPCReact, type inferReactQueryProcedureOptions,} from'@ trpc/rea ct-quer y';import type { inferRouterInputs, inferRouterOutputs } from '@trpc/server';import type{ AppRouter } from './server'; // infer the types for your router export type ReactQueryOptions = inferReactQueryProcedureOptions<AppRouter>;export type RouterInputs = inferRouterInputs<AppRouter>;export typeRouterOutputs = inferRouterOutputs<AppRouter>; exportconst trpc = createTRPCReact<AppRouter>();
trpc.tstsimport {createTRPCReact,type inferReactQueryProcedureOptions,} from'@ trpc/rea ct-quer y';import type { inferRouterInputs, inferRouterOutputs } from '@trpc/server';import type{ AppRouter } from './server'; // infer the types for your router export type ReactQueryOptions = inferReactQueryProcedureOptions<AppRouter>;export type RouterInputs = inferRouterInputs<AppRouter>;export typeRouterOutputs = inferRouterOutputs<AppRouter>; exportconst trpc = createTRPCReact<AppRouter>();
usePostCreate.tstsimport {trpc,type ReactQueryOptions,type RouterInputs, type RouterOutputs,} from './trpc';type PostCreateOptions= ReactQueryOptions['post']['create']; function usePostCreate(options?: PostCreateOptions) {const utils =trpc.useUtils(); returntrpc .post.create.useMutation({ ...options, onSuccess(post, variables, onMutateResult, context) { // invalidate all queries on the post router// when a new post is created utils.post.invalidate();options ?.onSuccess?.(post, variables, onMutateResult, context); },});}
usePostCreate.tstsimport {trpc,type ReactQueryOptions,type RouterInputs,type RouterOutputs,} from './trpc';type PostCreateOptions= ReactQueryOptions['post']['create']; function usePostCreate(options?: PostCreateOptions) {const utils =trpc.useUtils(); returntrpc.post.create. useMutation({ ...options,onSuccess(post, variables, onMutateResult, context) { // invalidate all queries on the post router// when a new post is created utils.post.invalidate();options?.onSuccess?.(post, variables, onMutateResult, context); },});}
usePostById.tstsimport {ReactQue ryOptions, RouterInputs, trpc } from './trpc';type PostByIdOptions = ReactQueryOptions['post']['byId'];typePostByIdInput = RouterInputs['post']['byId']; functionusePostById (input: PostByIdInput, options?: PostByIdOptions) { return trpc.post.byId.useQuery(input, options); }
usePostById.tstsimport {ReactQue ryOptions, RouterInputs, trpc } from './trpc';type PostByIdOptions = ReactQueryOptions['post']['byId'];typePostByIdInput = RouterInputs['post']['byId']; functionusePostById(input: PostByIdInput, options?: PostByIdOptions) { return trpc.post.byId.useQuery(input, options); }
Inférer des types abstraits depuis une "Router Factory"
Si vous implémentez une fabrique qui crée plusieurs fois une interface de routeur similaire dans votre application, vous pourriez vouloir partager du code client entre les différentes instances. @trpc/react-query/shared exporte plusieurs types permettant de générer des types abstraits pour une fabrique de routeurs, et de construire des composants React génériques qui reçoivent le routeur en tant que prop.
api/factory.tstsximport {z } from 'zod';import {t ,publicProcedure } from './trpc';// @trpc/react-query/shared exports several **Like types which can be used to generate abstract typesimport {RouterLike ,UtilsLike } from '@trpc/react-query/shared';constThingRequest =z .object ({name :z .string () });constThing =z .object ({id :z .string (),name :z .string () });constThingQuery =z .object ({filter :z .string ().optional () });constThingArray =z .array (Thing );// Factory function written by you, however you need,// so long as you can infer the resulting type of t.router() laterexport functioncreateMyRouter () {returnt .router ({createThing :publicProcedure .input (ThingRequest ).output (Thing ).mutation (({input }) => ({id : '1', ...input })),listThings :publicProcedure .input (ThingQuery ).output (ThingArray ).query (() => []),})}// Infer the type of your router, and then generate the abstract types for use in the clienttypeMyRouterType =ReturnType <typeofcreateMyRouter >export typeMyRouterLike =RouterLike <MyRouterType >export typeMyRouterUtilsLike =UtilsLike <MyRouterType >
api/factory.tstsximport {z } from 'zod';import {t ,publicProcedure } from './trpc';// @trpc/react-query/shared exports several **Like types which can be used to generate abstract typesimport {RouterLike ,UtilsLike } from '@trpc/react-query/shared';constThingRequest =z .object ({name :z .string () });constThing =z .object ({id :z .string (),name :z .string () });constThingQuery =z .object ({filter :z .string ().optional () });constThingArray =z .array (Thing );// Factory function written by you, however you need,// so long as you can infer the resulting type of t.router() laterexport functioncreateMyRouter () {returnt .router ({createThing :publicProcedure .input (ThingRequest ).output (Thing ).mutation (({input }) => ({id : '1', ...input })),listThings :publicProcedure .input (ThingQuery ).output (ThingArray ).query (() => []),})}// Infer the type of your router, and then generate the abstract types for use in the clienttypeMyRouterType =ReturnType <typeofcreateMyRouter >export typeMyRouterLike =RouterLike <MyRouterType >export typeMyRouterUtilsLike =UtilsLike <MyRouterType >
api/server.tstsxexport typeAppRouter = typeofappRouter ;// Export your MyRouter types to the clientexport type {MyRouterLike ,MyRouterUtilsLike } from './factory';
api/server.tstsxexport typeAppRouter = typeofappRouter ;// Export your MyRouter types to the clientexport type {MyRouterLike ,MyRouterUtilsLike } from './factory';
frontend/usePostCreate.tstsximport type {MyRouterLike ,MyRouterUtilsLike } from './factory';typeMyGenericComponentProps = {route :MyRouterLike ;utils :MyRouterUtilsLike ;};functionMyGenericComponent (props :MyGenericComponentProps ) {const {route } =props ;constthing =route .listThings .useQuery ({filter : 'qwerty',});constmutation =route .doThing .useMutation ({onSuccess () {props .utils .listThings .invalidate ();},});functionhandleClick () {mutation .mutate ({name : 'Thing 1',});}return null; /* ui */}functionMyPageComponent () {constutils =useUtils ();return (<MyGenericComponent route ={trpc .deep .route .things }utils ={utils .deep .route .things }/>);}functionMyOtherPageComponent () {constutils =useUtils ();return (<MyGenericComponent route ={trpc .different .things }utils ={utils .different .things }/>);}
frontend/usePostCreate.tstsximport type {MyRouterLike ,MyRouterUtilsLike } from './factory';typeMyGenericComponentProps = {route :MyRouterLike ;utils :MyRouterUtilsLike ;};functionMyGenericComponent (props :MyGenericComponentProps ) {const {route } =props ;constthing =route .listThings .useQuery ({filter : 'qwerty',});constmutation =route .doThing .useMutation ({onSuccess () {props .utils .listThings .invalidate ();},});functionhandleClick () {mutation .mutate ({name : 'Thing 1',});}return null; /* ui */}functionMyPageComponent () {constutils =useUtils ();return (<MyGenericComponent route ={trpc .deep .route .things }utils ={utils .deep .route .things }/>);}functionMyOtherPageComponent () {constutils =useUtils ();return (<MyGenericComponent route ={trpc .different .things }utils ={utils .different .things }/>);}
Un exemple de travail plus complet est disponible ici