Middlewares
You are able to add middleware(s) to a procedure with the t.procedure.use()
method. The middleware(s) will wrap the invocation of the procedure and must pass through its return value.
Authorization
In the example below, any call to a adminProcedure
will ensure that the user is an "admin" before executing.
ts
import {TRPCError ,initTRPC } from '@trpc/server';interfaceContext {user ?: {id : string;isAdmin : boolean;// [..]};}constt =initTRPC .context <Context >().create ();export constmiddleware =t .middleware ;export constpublicProcedure =t .procedure ;export constrouter =t .router ;constisAdmin =middleware (async ({ctx ,next }) => {if (!ctx .user ?.isAdmin ) {throw newTRPCError ({code : 'UNAUTHORIZED' });}returnnext ({ctx : {user :ctx .user ,},});});export constadminProcedure =publicProcedure .use (isAdmin );
ts
import {TRPCError ,initTRPC } from '@trpc/server';interfaceContext {user ?: {id : string;isAdmin : boolean;// [..]};}constt =initTRPC .context <Context >().create ();export constmiddleware =t .middleware ;export constpublicProcedure =t .procedure ;export constrouter =t .router ;constisAdmin =middleware (async ({ctx ,next }) => {if (!ctx .user ?.isAdmin ) {throw newTRPCError ({code : 'UNAUTHORIZED' });}returnnext ({ctx : {user :ctx .user ,},});});export constadminProcedure =publicProcedure .use (isAdmin );
ts
import {adminProcedure ,publicProcedure ,router } from './trpc';constadminRouter =router ({secretPlace :adminProcedure .query (() => 'a key'),});export constappRouter =router ({foo :publicProcedure .query (() => 'bar'),admin :adminRouter ,});
ts
import {adminProcedure ,publicProcedure ,router } from './trpc';constadminRouter =router ({secretPlace :adminProcedure .query (() => 'a key'),});export constappRouter =router ({foo :publicProcedure .query (() => 'bar'),admin :adminRouter ,});
See Error Handling to learn more about the TRPCError
thrown in the above example.
Logging
In the example below timings for queries are logged automatically.
ts
constloggerMiddleware =middleware (async ({path ,type ,next }) => {conststart =Date .now ();constresult = awaitnext ();constdurationMs =Date .now () -start ;result .ok ?logMock ('OK request timing:', {path ,type ,durationMs }):logMock ('Non-OK request timing', {path ,type ,durationMs });returnresult ;});export constloggedProcedure =publicProcedure .use (loggerMiddleware );
ts
constloggerMiddleware =middleware (async ({path ,type ,next }) => {conststart =Date .now ();constresult = awaitnext ();constdurationMs =Date .now () -start ;result .ok ?logMock ('OK request timing:', {path ,type ,durationMs }):logMock ('Non-OK request timing', {path ,type ,durationMs });returnresult ;});export constloggedProcedure =publicProcedure .use (loggerMiddleware );
ts
import{ loggedProcedu re,router } from './trpc';export const appRouter = router({foo: loggedProcedure.query(() => 'bar'), abc: loggedProcedure.query(() => 'def'), });
ts
import{ loggedProcedu re,router } from './trpc';export const appRouter = router({foo: loggedProcedure.query(() => 'bar'), abc: loggedProcedure.query(() => 'def'), });
Context Swapping
Context swapping in tRPC is a very powerful feature that allows you to create base procedures that dynamically infers new context in a flexible and typesafe manner.
Below we have an example of a middleware that changes properties of the context, and procedures will receive the new context value:
ts
typeContext = {// user is nullableuser ?: {id : string;};};constisAuthed =middleware (({ctx ,next }) => {// `ctx.user` is nullableif (!ctx .user ) {throw newTRPCError ({code : 'UNAUTHORIZED' });}returnnext ({ctx : {// ✅ user value is known to be non-null nowuser :ctx .user ,},});});constprotectedProcedure =publicProcedure .use (isAuthed );protectedProcedure .query (({ctx }) =>ctx .user );
ts
typeContext = {// user is nullableuser ?: {id : string;};};constisAuthed =middleware (({ctx ,next }) => {// `ctx.user` is nullableif (!ctx .user ) {throw newTRPCError ({code : 'UNAUTHORIZED' });}returnnext ({ctx : {// ✅ user value is known to be non-null nowuser :ctx .user ,},});});constprotectedProcedure =publicProcedure .use (isAuthed );protectedProcedure .query (({ctx }) =>ctx .user );
Extending middlewares
We have prefixed this as unstable_
as it's a new API, but you're safe to use it! Read more.
We have a powerful feature called .pipe()
which allows you to extend middlewares in a typesafe manner.
Below we have an example of a middleware that extends a base middleware(foo). Like the context swapping example above, piping middlewares will change properties of the context, and procedures will receive the new context value.
ts
constfooMiddleware =middleware (({next }) => {returnnext ({ctx : {foo : 'foo' asconst ,},});});constbarMiddleware =fooMiddleware .unstable_pipe (({ctx ,next }) => {ctx .foo ;returnnext ({ctx : {bar : 'bar' asconst ,},});});constbarProcedure =publicProcedure .use (barMiddleware );barProcedure .query (({ctx }) =>ctx .bar );
ts
constfooMiddleware =middleware (({next }) => {returnnext ({ctx : {foo : 'foo' asconst ,},});});constbarMiddleware =fooMiddleware .unstable_pipe (({ctx ,next }) => {ctx .foo ;returnnext ({ctx : {bar : 'bar' asconst ,},});});constbarProcedure =publicProcedure .use (barMiddleware );barProcedure .query (({ctx }) =>ctx .bar );
Beware that the order in which you pipe your middlewares matter and that the context must overlap. An example of a forbidden pipe is shown below. Here, the fooMiddleware
overrides the ctx.a
while barMiddleware
still expects the root context from the initialization in initTRPC
- so piping fooMiddleware
with barMiddleware
would not work, while piping barMiddleware
with fooMiddleware
does work.
ts
import {initTRPC } from '@trpc/server';constt =initTRPC .context <{a : {b : 'a';};}>().create ();constfooMiddleware =t .middleware (({ctx ,next }) => {ctx .a ; // 👈 fooMiddleware expects `ctx.a` to be an objectreturnnext ({ctx : {a : 'a' asconst , // 👈 `ctx.a` is no longer an object},});});constbarMiddleware =t .middleware (({ctx ,next }) => {ctx .a ; // 👈 barMiddleware expects `ctx.a` to be an objectreturnnext ({ctx : {foo : 'foo' asconst ,},});});// ❌ `ctx.a` does not overlap from `fooMiddleware` to `barMiddleware`Argument of type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _meta: object; }, { ...; }>' is not assignable to parameter of type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, { ...; }> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _meta: object; }, { ...; }>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, { ...; }>'. Types of property 'unstable_pipe' are incompatible. Type '<$Params extends import("/vercel/path0/www/node_modules/@trpc/server/dist/core/procedure").ProcedureParams<import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: import("/vercel/path0/www/node_modules/@trpc/server/dis...' is not assignable to type '<$Params extends import("/vercel/path0/www/node_modules/@trpc/server/dist/core/procedure").ProcedureParams<import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: import("/vercel/path0/www/node_modules/@trpc/server/dis...'. Two different types with this name exist, but they are unrelated. Types of parameters 'fn' and 'fn' are incompatible. Type 'import("/vercel/path0/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareBuilder<{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/form...' is not assignable to type 'import("/vercel/path0/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareBuilder<{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/form...'. Two different types with this name exist, but they are unrelated. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, any>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, any> | MiddlewareFunction<...>'. Type 'import("/vercel/path0/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareBuilder<{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/form...' is not assignable to type 'import("/vercel/path0/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareBuilder<{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/form...'. Two different types with this name exist, but they are unrelated. Types of property '_middlewares' are incompatible. Type 'import("/vercel/path0/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareFunction<{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/for...' is not assignable to type 'import("/vercel/path0/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareFunction<{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/for...'. Two different types with this name exist, but they are unrelated. Type 'import("/vercel/path0/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareFunction<{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/for...' is not assignable to type 'import("/vercel/path0/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareFunction<{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/for...'. Two different types with this name exist, but they are unrelated. Type '{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/formatter").DefaultErrorShape; transformer: import("/vercel/path0/www/node_modules/@trpc/server/d...' is not assignable to type '{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/formatter").DefaultErrorShape; transformer: import("/vercel/path0/www/node_modules/@trpc/server/d...'. Two different types with this name exist, but they are unrelated. Types of property '_ctx_out' are incompatible. Type 'Overwrite<{ a: { b: "a"; }; }, { foo: "foo"; }>' is not assignable to type 'Overwrite<Overwrite<{ a: { b: "a"; }; }, { a: "a"; }>, { foo: "foo"; }>'. Type 'Overwrite<{ a: { b: "a"; }; }, { foo: "foo"; }>' is not assignable to type 'Omit<Overwrite<{ a: { b: "a"; }; }, { a: "a"; }>, "foo">'. Types of property 'a' are incompatible. Type '{ b: "a"; }' is not assignable to type '"a"'.2345Argument of type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _meta: object; }, { ...; }>' is not assignable to parameter of type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, { ...; }> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _meta: object; }, { ...; }>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, { ...; }>'. Types of property 'unstable_pipe' are incompatible. Type '<$Params extends import("/vercel/path0/www/node_modules/@trpc/server/dist/core/procedure").ProcedureParams<import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: import("/vercel/path0/www/node_modules/@trpc/server/dis...' is not assignable to type '<$Params extends import("/vercel/path0/www/node_modules/@trpc/server/dist/core/procedure").ProcedureParams<import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: import("/vercel/path0/www/node_modules/@trpc/server/dis...'. Two different types with this name exist, but they are unrelated. Types of parameters 'fn' and 'fn' are incompatible. Type 'import("/vercel/path0/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareBuilder<{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/form...' is not assignable to type 'import("/vercel/path0/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareBuilder<{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/form...'. Two different types with this name exist, but they are unrelated. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, any>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, any> | MiddlewareFunction<...>'. Type 'import("/vercel/path0/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareBuilder<{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/form...' is not assignable to type 'import("/vercel/path0/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareBuilder<{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/form...'. Two different types with this name exist, but they are unrelated. Types of property '_middlewares' are incompatible. Type 'import("/vercel/path0/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareFunction<{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/for...' is not assignable to type 'import("/vercel/path0/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareFunction<{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/for...'. Two different types with this name exist, but they are unrelated. Type 'import("/vercel/path0/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareFunction<{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/for...' is not assignable to type 'import("/vercel/path0/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareFunction<{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/for...'. Two different types with this name exist, but they are unrelated. Type '{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/formatter").DefaultErrorShape; transformer: import("/vercel/path0/www/node_modules/@trpc/server/d...' is not assignable to type '{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/formatter").DefaultErrorShape; transformer: import("/vercel/path0/www/node_modules/@trpc/server/d...'. Two different types with this name exist, but they are unrelated. Types of property '_ctx_out' are incompatible. Type 'Overwrite<{ a: { b: "a"; }; }, { foo: "foo"; }>' is not assignable to type 'Overwrite<Overwrite<{ a: { b: "a"; }; }, { a: "a"; }>, { foo: "foo"; }>'. Type 'Overwrite<{ a: { b: "a"; }; }, { foo: "foo"; }>' is not assignable to type 'Omit<Overwrite<{ a: { b: "a"; }; }, { a: "a"; }>, "foo">'. Types of property 'a' are incompatible. Type '{ b: "a"; }' is not assignable to type '"a"'.fooMiddleware .unstable_pipe (); barMiddleware // ✅ `ctx.a` overlaps from `barMiddleware` and `fooMiddleware`barMiddleware .unstable_pipe (fooMiddleware );
ts
import {initTRPC } from '@trpc/server';constt =initTRPC .context <{a : {b : 'a';};}>().create ();constfooMiddleware =t .middleware (({ctx ,next }) => {ctx .a ; // 👈 fooMiddleware expects `ctx.a` to be an objectreturnnext ({ctx : {a : 'a' asconst , // 👈 `ctx.a` is no longer an object},});});constbarMiddleware =t .middleware (({ctx ,next }) => {ctx .a ; // 👈 barMiddleware expects `ctx.a` to be an objectreturnnext ({ctx : {foo : 'foo' asconst ,},});});// ❌ `ctx.a` does not overlap from `fooMiddleware` to `barMiddleware`Argument of type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _meta: object; }, { ...; }>' is not assignable to parameter of type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, { ...; }> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _meta: object; }, { ...; }>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, { ...; }>'. Types of property 'unstable_pipe' are incompatible. Type '<$Params extends import("/vercel/path0/www/node_modules/@trpc/server/dist/core/procedure").ProcedureParams<import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: import("/vercel/path0/www/node_modules/@trpc/server/dis...' is not assignable to type '<$Params extends import("/vercel/path0/www/node_modules/@trpc/server/dist/core/procedure").ProcedureParams<import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: import("/vercel/path0/www/node_modules/@trpc/server/dis...'. Two different types with this name exist, but they are unrelated. Types of parameters 'fn' and 'fn' are incompatible. Type 'import("/vercel/path0/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareBuilder<{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/form...' is not assignable to type 'import("/vercel/path0/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareBuilder<{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/form...'. Two different types with this name exist, but they are unrelated. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, any>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, any> | MiddlewareFunction<...>'. Type 'import("/vercel/path0/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareBuilder<{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/form...' is not assignable to type 'import("/vercel/path0/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareBuilder<{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/form...'. Two different types with this name exist, but they are unrelated. Types of property '_middlewares' are incompatible. Type 'import("/vercel/path0/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareFunction<{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/for...' is not assignable to type 'import("/vercel/path0/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareFunction<{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/for...'. Two different types with this name exist, but they are unrelated. Type 'import("/vercel/path0/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareFunction<{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/for...' is not assignable to type 'import("/vercel/path0/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareFunction<{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/for...'. Two different types with this name exist, but they are unrelated. Type '{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/formatter").DefaultErrorShape; transformer: import("/vercel/path0/www/node_modules/@trpc/server/d...' is not assignable to type '{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/formatter").DefaultErrorShape; transformer: import("/vercel/path0/www/node_modules/@trpc/server/d...'. Two different types with this name exist, but they are unrelated. Types of property '_ctx_out' are incompatible. Type 'Overwrite<{ a: { b: "a"; }; }, { foo: "foo"; }>' is not assignable to type 'Overwrite<Overwrite<{ a: { b: "a"; }; }, { a: "a"; }>, { foo: "foo"; }>'. Type 'Overwrite<{ a: { b: "a"; }; }, { foo: "foo"; }>' is not assignable to type 'Omit<Overwrite<{ a: { b: "a"; }; }, { a: "a"; }>, "foo">'. Types of property 'a' are incompatible. Type '{ b: "a"; }' is not assignable to type '"a"'.2345Argument of type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _meta: object; }, { ...; }>' is not assignable to parameter of type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, { ...; }> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _meta: object; }, { ...; }>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, { ...; }>'. Types of property 'unstable_pipe' are incompatible. Type '<$Params extends import("/vercel/path0/www/node_modules/@trpc/server/dist/core/procedure").ProcedureParams<import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: import("/vercel/path0/www/node_modules/@trpc/server/dis...' is not assignable to type '<$Params extends import("/vercel/path0/www/node_modules/@trpc/server/dist/core/procedure").ProcedureParams<import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: import("/vercel/path0/www/node_modules/@trpc/server/dis...'. Two different types with this name exist, but they are unrelated. Types of parameters 'fn' and 'fn' are incompatible. Type 'import("/vercel/path0/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareBuilder<{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/form...' is not assignable to type 'import("/vercel/path0/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareBuilder<{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/form...'. Two different types with this name exist, but they are unrelated. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, any>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, any> | MiddlewareFunction<...>'. Type 'import("/vercel/path0/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareBuilder<{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/form...' is not assignable to type 'import("/vercel/path0/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareBuilder<{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/form...'. Two different types with this name exist, but they are unrelated. Types of property '_middlewares' are incompatible. Type 'import("/vercel/path0/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareFunction<{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/for...' is not assignable to type 'import("/vercel/path0/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareFunction<{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/for...'. Two different types with this name exist, but they are unrelated. Type 'import("/vercel/path0/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareFunction<{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/for...' is not assignable to type 'import("/vercel/path0/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareFunction<{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/for...'. Two different types with this name exist, but they are unrelated. Type '{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/formatter").DefaultErrorShape; transformer: import("/vercel/path0/www/node_modules/@trpc/server/d...' is not assignable to type '{ _config: import("/vercel/path0/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/vercel/path0/www/node_modules/@trpc/server/dist/error/formatter").DefaultErrorShape; transformer: import("/vercel/path0/www/node_modules/@trpc/server/d...'. Two different types with this name exist, but they are unrelated. Types of property '_ctx_out' are incompatible. Type 'Overwrite<{ a: { b: "a"; }; }, { foo: "foo"; }>' is not assignable to type 'Overwrite<Overwrite<{ a: { b: "a"; }; }, { a: "a"; }>, { foo: "foo"; }>'. Type 'Overwrite<{ a: { b: "a"; }; }, { foo: "foo"; }>' is not assignable to type 'Omit<Overwrite<{ a: { b: "a"; }; }, { a: "a"; }>, "foo">'. Types of property 'a' are incompatible. Type '{ b: "a"; }' is not assignable to type '"a"'.fooMiddleware .unstable_pipe (); barMiddleware // ✅ `ctx.a` overlaps from `barMiddleware` and `fooMiddleware`barMiddleware .unstable_pipe (fooMiddleware );