Skip to main content
Version: 10.x

中间件

你可以使用 t.procedure.use() 方法将中间件添加到过程中。中间件将封装过程的调用,并且必须传递其返回值。

¥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

在下面的示例中,任何对 adminProcedure 的调用都会在执行之前确保用户是 "admin"。

¥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';
 
interface Context {
user?: {
id: string;
isAdmin: boolean;
// [..]
};
}
 
const t = initTRPC.context<Context>().create();
export const publicProcedure = t.procedure;
export const router = t.router;
 
export const adminProcedure = publicProcedure.use(async (opts) => {
const { ctx } = opts;
if (!ctx.user?.isAdmin) {
throw new TRPCError({ code: 'UNAUTHORIZED' });
}
return opts.next({
ctx: {
user: ctx.user,
},
});
});
ts
import { TRPCError, initTRPC } from '@trpc/server';
 
interface Context {
user?: {
id: string;
isAdmin: boolean;
// [..]
};
}
 
const t = initTRPC.context<Context>().create();
export const publicProcedure = t.procedure;
export const router = t.router;
 
export const adminProcedure = publicProcedure.use(async (opts) => {
const { ctx } = opts;
if (!ctx.user?.isAdmin) {
throw new TRPCError({ code: 'UNAUTHORIZED' });
}
return opts.next({
ctx: {
user: ctx.user,
},
});
});
ts
import { adminProcedure, publicProcedure, router } from './trpc';
 
const adminRouter = router({
secretPlace: adminProcedure.query(() => 'a key'),
});
 
export const appRouter = router({
foo: publicProcedure.query(() => 'bar'),
admin: adminRouter,
});
ts
import { adminProcedure, publicProcedure, router } from './trpc';
 
const adminRouter = router({
secretPlace: adminProcedure.query(() => 'a key'),
});
 
export const appRouter = router({
foo: publicProcedure.query(() => 'bar'),
admin: adminRouter,
});
提示

请参阅 错误处理 以了解有关上例中抛出的 TRPCError 的更多信息。

¥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
export const loggedProcedure = publicProcedure.use(async (opts) => {
const start = Date.now();
 
const result = await opts.next();
 
const durationMs = Date.now() - start;
const meta = { path: opts.path, type: opts.type, durationMs };
 
result.ok
? console.log('OK request timing:', meta)
: console.error('Non-OK request timing', meta);
 
return result;
});
ts
export const loggedProcedure = publicProcedure.use(async (opts) => {
const start = Date.now();
 
const result = await opts.next();
 
const durationMs = Date.now() - start;
const meta = { path: opts.path, type: opts.type, durationMs };
 
result.ok
? console.log('OK request timing:', meta)
: console.error('Non-OK request timing', meta);
 
return result;
});
ts
import { loggedProcedure, router } from './trpc';
 
export const appRouter = router({
foo: loggedProcedure.query(() => 'bar'),
abc: loggedProcedure.query(() => 'def'),
});
ts
import { loggedProcedure, router } from './trpc';
 
export const appRouter = router({
foo: loggedProcedure.query(() => 'bar'),
abc: loggedProcedure.query(() => 'def'),
});

上下文扩展

¥Context Extension

"上下文扩展" 使中间件能够以类型安全的方式在基本过程的上下文中动态添加和覆盖键。

¥"Context Extension" enables middlewares to dynamically add and override keys on a base procedure's context in a typesafe manner.

下面我们有一个中间件的示例,它更改上下文的属性,然后这些更改可供所有链式消费者使用,例如其他中间件和过程:

¥Below we have an example of a middleware that changes properties of a context, the changes are then available to all chained consumers, such as other middlewares and procedures:

ts
type Context = {
// user is nullable
user?: {
id: string;
};
};
 
const protectedProcedure = publicProcedure.use(async function isAuthed(opts) {
const { ctx } = opts;
// `ctx.user` is nullable
if (!ctx.user) {
(property) user: { id: string; } | undefined
throw new TRPCError({ code: 'UNAUTHORIZED' });
}
 
return opts.next({
ctx: {
// ✅ user value is known to be non-null now
user: ctx.user,
(property) user: { id: string; }
},
});
});
 
protectedProcedure.query(({ ctx }) => ctx.user);
(property) user: { id: string; }
ts
type Context = {
// user is nullable
user?: {
id: string;
};
};
 
const protectedProcedure = publicProcedure.use(async function isAuthed(opts) {
const { ctx } = opts;
// `ctx.user` is nullable
if (!ctx.user) {
(property) user: { id: string; } | undefined
throw new TRPCError({ code: 'UNAUTHORIZED' });
}
 
return opts.next({
ctx: {
// ✅ user value is known to be non-null now
user: ctx.user,
(property) user: { id: string; }
},
});
});
 
protectedProcedure.query(({ ctx }) => ctx.user);
(property) user: { id: string; }

扩展中间件

¥Extending middlewares

信息

我们已将其前缀为 unstable_,因为它是一个新 API,但你可以安全地使用它!阅读更多

¥We have prefixed this as unstable_ as it's a new API, but you're safe to use it! Read more.

我们有一个名为 .pipe() 的强大功能,它允许你以类型安全的方式扩展中间件。

¥We have a powerful feature called .pipe() which allows you to extend middlewares in a typesafe manner.

下面我们有一个扩展基础中间件(foo)的中间件示例。与上面的上下文扩展示例一样,管道中间件将更改上下文的属性,并且过程将接收新的上下文值。

¥Below we have an example of a middleware that extends a base middleware(foo). Like the context extension example above, piping middlewares will change properties of the context, and procedures will receive the new context value.

ts
const fooMiddleware = t.middleware((opts) => {
return opts.next({
ctx: {
foo: 'foo' as const,
},
});
});
 
const barMiddleware = fooMiddleware.unstable_pipe((opts) => {
const { ctx } = opts;
ctx.foo;
(property) foo: "foo"
return opts.next({
ctx: {
bar: 'bar' as const,
},
});
});
 
const barProcedure = publicProcedure.use(barMiddleware);
barProcedure.query(({ ctx }) => ctx.bar);
(parameter) ctx: { foo: "foo"; bar: "bar"; }
ts
const fooMiddleware = t.middleware((opts) => {
return opts.next({
ctx: {
foo: 'foo' as const,
},
});
});
 
const barMiddleware = fooMiddleware.unstable_pipe((opts) => {
const { ctx } = opts;
ctx.foo;
(property) foo: "foo"
return opts.next({
ctx: {
bar: 'bar' as const,
},
});
});
 
const barProcedure = publicProcedure.use(barMiddleware);
barProcedure.query(({ ctx }) => ctx.bar);
(parameter) ctx: { foo: "foo"; bar: "bar"; }

请注意,中间件的管道顺序很重要,并且上下文必须重叠。禁止管道的示例如下所示。这里,fooMiddleware 覆盖了 ctx.a,而 barMiddleware 仍然期望来自 initTRPC 中初始化的根上下文 - 因此,将 fooMiddlewarebarMiddleware 进行管道连接将不起作用,而将 barMiddlewarefooMiddleware 进行管道连接则可以工作。

¥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';
 
const t = initTRPC
.context<{
a: {
b: 'a';
};
}>()
.create();
 
const fooMiddleware = t.middleware((opts) => {
const { ctx } = opts;
ctx.a; // 👈 fooMiddleware expects `ctx.a` to be an object
(property) a: { b: 'a'; }
return opts.next({
ctx: {
a: 'a' as const, // 👈 `ctx.a` is no longer an object
},
});
});
 
const barMiddleware = t.middleware((opts) => {
const { ctx } = opts;
ctx.a; // 👈 barMiddleware expects `ctx.a` to be an object
(property) a: { b: 'a'; }
return opts.next({
ctx: {
foo: 'foo' as const,
},
});
});
 
// ❌ `ctx.a` does not overlap from `fooMiddleware` to `barMiddleware`
fooMiddleware.unstable_pipe(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("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/procedure").ProcedureParams<import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: import("/Users/q/co...' is not assignable to type '<$Params extends import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/procedure").ProcedureParams<import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: import("/Users/q/co...'. Two different types with this name exist, but they are unrelated. Types of parameters 'fn' and 'fn' are incompatible. Type 'import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareBuilder<{ _config: import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/Users/q/code/nodejscn/...' is not assignable to type 'import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareBuilder<{ _config: import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/Users/q/code/nodejscn/...'. 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("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareBuilder<{ _config: import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/Users/q/code/nodejscn/...' is not assignable to type 'import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareBuilder<{ _config: import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/Users/q/code/nodejscn/...'. Two different types with this name exist, but they are unrelated. Types of property '_middlewares' are incompatible. Type 'import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareFunction<{ _config: import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/Users/q/code/nodejscn...' is not assignable to type 'import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareFunction<{ _config: import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/Users/q/code/nodejscn...'. Two different types with this name exist, but they are unrelated. Type 'import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareFunction<{ _config: import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/Users/q/code/nodejscn...' is not assignable to type 'import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareFunction<{ _config: import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/Users/q/code/nodejscn...'. Two different types with this name exist, but they are unrelated. Types of parameters 'opts' and 'opts' are incompatible. Type '{ ctx: { a: { b: "a"; }; foo: "foo"; }; type: "query" | "mutation" | "subscription"; path: string; input: unknown; rawInput: unknown; meta: object | undefined; next: { (): Promise<MiddlewareResult<{ _config: RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataT...' is not assignable to type '{ ctx: { a: "a"; foo: "foo"; }; type: "query" | "mutation" | "subscription"; path: string; input: unknown; rawInput: unknown; meta: object | undefined; next: { (): Promise<MiddlewareResult<{ _config: RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransform...'. The types of 'ctx.a' are incompatible between these types. 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("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/procedure").ProcedureParams<import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: import("/Users/q/co...' is not assignable to type '<$Params extends import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/procedure").ProcedureParams<import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: import("/Users/q/co...'. Two different types with this name exist, but they are unrelated. Types of parameters 'fn' and 'fn' are incompatible. Type 'import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareBuilder<{ _config: import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/Users/q/code/nodejscn/...' is not assignable to type 'import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareBuilder<{ _config: import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/Users/q/code/nodejscn/...'. 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("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareBuilder<{ _config: import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/Users/q/code/nodejscn/...' is not assignable to type 'import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareBuilder<{ _config: import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/Users/q/code/nodejscn/...'. Two different types with this name exist, but they are unrelated. Types of property '_middlewares' are incompatible. Type 'import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareFunction<{ _config: import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/Users/q/code/nodejscn...' is not assignable to type 'import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareFunction<{ _config: import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/Users/q/code/nodejscn...'. Two different types with this name exist, but they are unrelated. Type 'import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareFunction<{ _config: import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/Users/q/code/nodejscn...' is not assignable to type 'import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareFunction<{ _config: import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/Users/q/code/nodejscn...'. Two different types with this name exist, but they are unrelated. Types of parameters 'opts' and 'opts' are incompatible. Type '{ ctx: { a: { b: "a"; }; foo: "foo"; }; type: "query" | "mutation" | "subscription"; path: string; input: unknown; rawInput: unknown; meta: object | undefined; next: { (): Promise<MiddlewareResult<{ _config: RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataT...' is not assignable to type '{ ctx: { a: "a"; foo: "foo"; }; type: "query" | "mutation" | "subscription"; path: string; input: unknown; rawInput: unknown; meta: object | undefined; next: { (): Promise<MiddlewareResult<{ _config: RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransform...'. The types of 'ctx.a' are incompatible between these types. Type '{ b: "a"; }' is not assignable to type '"a"'.
 
// ✅ `ctx.a` overlaps from `barMiddleware` and `fooMiddleware`
barMiddleware.unstable_pipe(fooMiddleware);
ts
import { initTRPC } from '@trpc/server';
 
const t = initTRPC
.context<{
a: {
b: 'a';
};
}>()
.create();
 
const fooMiddleware = t.middleware((opts) => {
const { ctx } = opts;
ctx.a; // 👈 fooMiddleware expects `ctx.a` to be an object
(property) a: { b: 'a'; }
return opts.next({
ctx: {
a: 'a' as const, // 👈 `ctx.a` is no longer an object
},
});
});
 
const barMiddleware = t.middleware((opts) => {
const { ctx } = opts;
ctx.a; // 👈 barMiddleware expects `ctx.a` to be an object
(property) a: { b: 'a'; }
return opts.next({
ctx: {
foo: 'foo' as const,
},
});
});
 
// ❌ `ctx.a` does not overlap from `fooMiddleware` to `barMiddleware`
fooMiddleware.unstable_pipe(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("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/procedure").ProcedureParams<import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: import("/Users/q/co...' is not assignable to type '<$Params extends import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/procedure").ProcedureParams<import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: import("/Users/q/co...'. Two different types with this name exist, but they are unrelated. Types of parameters 'fn' and 'fn' are incompatible. Type 'import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareBuilder<{ _config: import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/Users/q/code/nodejscn/...' is not assignable to type 'import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareBuilder<{ _config: import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/Users/q/code/nodejscn/...'. 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("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareBuilder<{ _config: import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/Users/q/code/nodejscn/...' is not assignable to type 'import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareBuilder<{ _config: import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/Users/q/code/nodejscn/...'. Two different types with this name exist, but they are unrelated. Types of property '_middlewares' are incompatible. Type 'import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareFunction<{ _config: import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/Users/q/code/nodejscn...' is not assignable to type 'import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareFunction<{ _config: import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/Users/q/code/nodejscn...'. Two different types with this name exist, but they are unrelated. Type 'import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareFunction<{ _config: import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/Users/q/code/nodejscn...' is not assignable to type 'import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareFunction<{ _config: import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/Users/q/code/nodejscn...'. Two different types with this name exist, but they are unrelated. Types of parameters 'opts' and 'opts' are incompatible. Type '{ ctx: { a: { b: "a"; }; foo: "foo"; }; type: "query" | "mutation" | "subscription"; path: string; input: unknown; rawInput: unknown; meta: object | undefined; next: { (): Promise<MiddlewareResult<{ _config: RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataT...' is not assignable to type '{ ctx: { a: "a"; foo: "foo"; }; type: "query" | "mutation" | "subscription"; path: string; input: unknown; rawInput: unknown; meta: object | undefined; next: { (): Promise<MiddlewareResult<{ _config: RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransform...'. The types of 'ctx.a' are incompatible between these types. 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("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/procedure").ProcedureParams<import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: import("/Users/q/co...' is not assignable to type '<$Params extends import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/procedure").ProcedureParams<import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: import("/Users/q/co...'. Two different types with this name exist, but they are unrelated. Types of parameters 'fn' and 'fn' are incompatible. Type 'import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareBuilder<{ _config: import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/Users/q/code/nodejscn/...' is not assignable to type 'import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareBuilder<{ _config: import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/Users/q/code/nodejscn/...'. 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("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareBuilder<{ _config: import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/Users/q/code/nodejscn/...' is not assignable to type 'import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareBuilder<{ _config: import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/Users/q/code/nodejscn/...'. Two different types with this name exist, but they are unrelated. Types of property '_middlewares' are incompatible. Type 'import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareFunction<{ _config: import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/Users/q/code/nodejscn...' is not assignable to type 'import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareFunction<{ _config: import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/Users/q/code/nodejscn...'. Two different types with this name exist, but they are unrelated. Type 'import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareFunction<{ _config: import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/Users/q/code/nodejscn...' is not assignable to type 'import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/middleware").MiddlewareFunction<{ _config: import("/Users/q/code/nodejscn/trpc/src/www/node_modules/@trpc/server/dist/core/internals/config").RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: import("/Users/q/code/nodejscn...'. Two different types with this name exist, but they are unrelated. Types of parameters 'opts' and 'opts' are incompatible. Type '{ ctx: { a: { b: "a"; }; foo: "foo"; }; type: "query" | "mutation" | "subscription"; path: string; input: unknown; rawInput: unknown; meta: object | undefined; next: { (): Promise<MiddlewareResult<{ _config: RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataT...' is not assignable to type '{ ctx: { a: "a"; foo: "foo"; }; type: "query" | "mutation" | "subscription"; path: string; input: unknown; rawInput: unknown; meta: object | undefined; next: { (): Promise<MiddlewareResult<{ _config: RootConfig<{ ctx: { a: { b: "a"; }; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransform...'. The types of 'ctx.a' are incompatible between these types. Type '{ b: "a"; }' is not assignable to type '"a"'.
 
// ✅ `ctx.a` overlaps from `barMiddleware` and `fooMiddleware`
barMiddleware.unstable_pipe(fooMiddleware);

实验:独立中间件

¥Experimental: standalone middlewares

信息

警告:我们已将其前缀为 experimental_,并且它可能会随任何 tRPC 版本而更改。阅读更多

¥Caution: we have prefixed this as experimental_ and it may change with any tRPC release. Read more.

tRPC 有一个名为 experimental_standaloneMiddleware 的新实验性 API,它允许你独立定义可与任何 tRPC 实例一起使用的中间件。使用 t.middleware 创建中间件有一个限制,即 Context 类型与 tRPC 实例的 Context 类型相关联。这意味着你不能将相同的中间件与具有不同 Context 类型的多个 tRPC 实例一起使用。

¥tRPC has a new experimental API called experimental_standaloneMiddleware which allows you to independently define a middleware that can be used with any tRPC instance. Creating middlewares using t.middleware has the limitation that the Context type is tied to the Context type of the tRPC instance. This means that you cannot use the same middleware with multiple tRPC instances that have different Context types.

使用 experimental_standaloneMiddleware,你可以创建一个显式定义其要求的中间件,即上下文、输入和元类型:

¥Using experimental_standaloneMiddleware you can create a middleware that explicitly defines its requirements, i.e. the Context, Input and Meta types:

ts
import {
experimental_standaloneMiddleware,
initTRPC,
TRPCError,
} from '@trpc/server';
import * as z from 'zod';
 
const projectAccessMiddleware = experimental_standaloneMiddleware<{
ctx: { allowedProjects: string[] }; // defaults to 'object' if not defined
input: { projectId: string }; // defaults to 'unknown' if not defined
// 'meta', not defined here, defaults to 'object | undefined'
}>().create((opts) => {
if (!opts.ctx.allowedProjects.includes(opts.input.projectId)) {
throw new TRPCError({
code: 'FORBIDDEN',
message: 'Not allowed',
});
}
 
return opts.next();
});
 
const t1 = initTRPC
.context<{
allowedProjects: string[];
}>()
.create();
 
// ✅ `ctx.allowedProjects` satisfies "string[]" and `input.projectId` satisfies "string"
const accessControlledProcedure = t1.procedure
.input(z.object({ projectId: z.string() }))
.use(projectAccessMiddleware);
 
// ❌ `ctx.allowedProjects` satisfies "string[]" but `input.projectId` does not satisfy "string"
const accessControlledProcedure2 = t1.procedure
.input(z.object({ projectId: z.number() }))
.use(projectAccessMiddleware);
Argument of type 'MiddlewareBuilder<deriveParamsFromConfig<RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>, { projectId: string; }>, deriveParamsFromConfig<...>>' is not assignable to parameter of type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unique symbol; }, deriveParamsFromConfig<...>> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<deriveParamsFromConfig<RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>, { projectId: string; }>, deriveParamsFromConfig<...>>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unique symbol; }, deriveParamsFromConfig<...>>'. Types of property 'unstable_pipe' are incompatible. Type '<$Params extends ProcedureParams<AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; ... 5 more ...; _output_out: unknown; }, $Params> | MiddlewareFunction<....' is not assignable to type '<$Params extends ProcedureParams<AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, $Par...'. Types of parameters 'fn' and 'fn' are incompatible. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, any> | MiddlewareFunction<...>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {}; _input_in: { projectId: string; }; _input_out: unique symbol; _output_in: unknown; _output_out: unknown; }, any> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, any>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {}; _input_in: { projectId: string; }; _input_out: unique symbol; _output_in: unknown; _output_out: unknown; }, any> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, any>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {}; _input_in: { projectId: string; }; _input_out: unique symbol; _output_in: unknown; _output_out: unknown; }, any>'. Types of property 'unstable_pipe' are incompatible. Type '<$Params extends ProcedureParams<AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: any; }, $Params>...' is not assignable to type '<$Params extends ProcedureParams<AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; ... 5 more ...; _output_out: any; }, $Params> | MiddlewareFunction<...>)...'. Types of parameters 'fn' and 'fn' are incompatible. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {} & { [key: string]: any; }; _input_in: { ...; }; _input_out: any; _output_in: any; _output_out: any; }, any> | MiddlewareFunction<...>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: any; }, any> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {} & { [key: string]: any; }; _input_in: { ...; }; _input_out: any; _output_in: any; _output_out: any; }, any>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: any; }, any> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {} & { [key: string]: any; }; _input_in: { ...; }; _input_out: any; _output_in: any; _output_out: any; }, any>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: any; }, any>'. Types of property '_middlewares' are incompatible. Type 'MiddlewareFunction<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {} & { [key: string]: any; }; _input_in: { ...; }; _input_out: any; _output_in: any; _output_out: any; }, any>[]' is not assignable to type 'MiddlewareFunction<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: any; }, any>[]'. Type 'MiddlewareFunction<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {} & { [key: string]: any; }; _input_in: { ...; }; _input_out: any; _output_in: any; _output_out: any; }, any>' is not assignable to type 'MiddlewareFunction<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: any; }, any>'. Types of parameters 'opts' and 'opts' are incompatible. Type '{ ctx: { [x: string]: any; allowedProjects: any; }; type: "query" | "mutation" | "subscription"; path: string; input: { projectId: number; }; rawInput: unknown; meta: object | undefined; next: { (): Promise<MiddlewareResult<{ ...; }>>; <$Context>(opts: { ...; }): Promise<...>; (opts: { ...; }): Promise<...>; }; }' is not assignable to type '{ ctx: { [x: string]: any; allowedProjects: any; }; type: "query" | "mutation" | "subscription"; path: string; input: { projectId: string; }; rawInput: unknown; meta: object | undefined; next: { (): Promise<MiddlewareResult<{ ...; }>>; <$Context>(opts: { ...; }): Promise<...>; (opts: { ...; }): Promise<...>; }; }'. The types of 'input.projectId' are incompatible between these types. Type 'number' is not assignable to type 'string'.2345Argument of type 'MiddlewareBuilder<deriveParamsFromConfig<RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>, { projectId: string; }>, deriveParamsFromConfig<...>>' is not assignable to parameter of type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unique symbol; }, deriveParamsFromConfig<...>> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<deriveParamsFromConfig<RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>, { projectId: string; }>, deriveParamsFromConfig<...>>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unique symbol; }, deriveParamsFromConfig<...>>'. Types of property 'unstable_pipe' are incompatible. Type '<$Params extends ProcedureParams<AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; ... 5 more ...; _output_out: unknown; }, $Params> | MiddlewareFunction<....' is not assignable to type '<$Params extends ProcedureParams<AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, $Par...'. Types of parameters 'fn' and 'fn' are incompatible. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, any> | MiddlewareFunction<...>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {}; _input_in: { projectId: string; }; _input_out: unique symbol; _output_in: unknown; _output_out: unknown; }, any> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, any>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {}; _input_in: { projectId: string; }; _input_out: unique symbol; _output_in: unknown; _output_out: unknown; }, any> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, any>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {}; _input_in: { projectId: string; }; _input_out: unique symbol; _output_in: unknown; _output_out: unknown; }, any>'. Types of property 'unstable_pipe' are incompatible. Type '<$Params extends ProcedureParams<AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: any; }, $Params>...' is not assignable to type '<$Params extends ProcedureParams<AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; ... 5 more ...; _output_out: any; }, $Params> | MiddlewareFunction<...>)...'. Types of parameters 'fn' and 'fn' are incompatible. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {} & { [key: string]: any; }; _input_in: { ...; }; _input_out: any; _output_in: any; _output_out: any; }, any> | MiddlewareFunction<...>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: any; }, any> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {} & { [key: string]: any; }; _input_in: { ...; }; _input_out: any; _output_in: any; _output_out: any; }, any>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: any; }, any> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {} & { [key: string]: any; }; _input_in: { ...; }; _input_out: any; _output_in: any; _output_out: any; }, any>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: any; }, any>'. Types of property '_middlewares' are incompatible. Type 'MiddlewareFunction<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {} & { [key: string]: any; }; _input_in: { ...; }; _input_out: any; _output_in: any; _output_out: any; }, any>[]' is not assignable to type 'MiddlewareFunction<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: any; }, any>[]'. Type 'MiddlewareFunction<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {} & { [key: string]: any; }; _input_in: { ...; }; _input_out: any; _output_in: any; _output_out: any; }, any>' is not assignable to type 'MiddlewareFunction<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: any; }, any>'. Types of parameters 'opts' and 'opts' are incompatible. Type '{ ctx: { [x: string]: any; allowedProjects: any; }; type: "query" | "mutation" | "subscription"; path: string; input: { projectId: number; }; rawInput: unknown; meta: object | undefined; next: { (): Promise<MiddlewareResult<{ ...; }>>; <$Context>(opts: { ...; }): Promise<...>; (opts: { ...; }): Promise<...>; }; }' is not assignable to type '{ ctx: { [x: string]: any; allowedProjects: any; }; type: "query" | "mutation" | "subscription"; path: string; input: { projectId: string; }; rawInput: unknown; meta: object | undefined; next: { (): Promise<MiddlewareResult<{ ...; }>>; <$Context>(opts: { ...; }): Promise<...>; (opts: { ...; }): Promise<...>; }; }'. The types of 'input.projectId' are incompatible between these types. Type 'number' is not assignable to type 'string'.
 
// ❌ `ctx.allowedProjects` does not satisfy "string[]" even though `input.projectId` satisfies "string"
const t2 = initTRPC
.context<{
allowedProjects: number[];
}>()
.create();
 
const accessControlledProcedure3 = t2.procedure
.input(z.object({ projectId: z.string() }))
.use(projectAccessMiddleware);
Argument of type 'MiddlewareBuilder<deriveParamsFromConfig<RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>, { projectId: string; }>, deriveParamsFromConfig<...>>' is not assignable to parameter of type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: number[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unique symbol; }, deriveParamsFromConfig<...>> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<deriveParamsFromConfig<RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>, { projectId: string; }>, deriveParamsFromConfig<...>>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: number[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unique symbol; }, deriveParamsFromConfig<...>>'. Types of property 'unstable_pipe' are incompatible. Type '<$Params extends ProcedureParams<AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; ... 5 more ...; _output_out: unknown; }, $Params> | MiddlewareFunction<....' is not assignable to type '<$Params extends ProcedureParams<AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: number[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, $Par...'. Types of parameters 'fn' and 'fn' are incompatible. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: number[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, any> | MiddlewareFunction<...>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {}; _input_in: { projectId: string; }; _input_out: unique symbol; _output_in: unknown; _output_out: unknown; }, any> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: number[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, any>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {}; _input_in: { projectId: string; }; _input_out: unique symbol; _output_in: unknown; _output_out: unknown; }, any> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: number[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, any>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {}; _input_in: { projectId: string; }; _input_out: unique symbol; _output_in: unknown; _output_out: unknown; }, any>'. The types of 'unstable_pipe(...)._middlewares' are incompatible between these types. Type 'MiddlewareFunction<{ _config: RootConfig<{ ctx: { allowedProjects: number[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, { ...; }>[]' is not assignable to type 'MiddlewareFunction<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {}; _input_in: { projectId: string; }; _input_out: unique symbol; _output_in: unknown; _output_out: unknown; }, { ...; }>[]'. Type 'MiddlewareFunction<{ _config: RootConfig<{ ctx: { allowedProjects: number[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, { ...; }>' is not assignable to type 'MiddlewareFunction<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {}; _input_in: { projectId: string; }; _input_out: unique symbol; _output_in: unknown; _output_out: unknown; }, { ...; }>'. Types of parameters 'opts' and 'opts' are incompatible. Type '{ ctx: { allowedProjects: string[]; }; type: "query" | "mutation" | "subscription"; path: string; input: { projectId: string; }; rawInput: unknown; meta: object | undefined; next: { (): Promise<MiddlewareResult<{ _config: RootConfig<{ ctx: { ...; }; meta: object; errorShape: object; transformer: object; }>; ... 5 mo...' is not assignable to type '{ ctx: { allowedProjects: number[]; }; type: "query" | "mutation" | "subscription"; path: string; input: { projectId: string; }; rawInput: unknown; meta: object | undefined; next: { (): Promise<MiddlewareResult<{ _config: RootConfig<{ ctx: { ...; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDa...'. The types of 'ctx.allowedProjects' are incompatible between these types. Type 'string[]' is not assignable to type 'number[]'.2345Argument of type 'MiddlewareBuilder<deriveParamsFromConfig<RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>, { projectId: string; }>, deriveParamsFromConfig<...>>' is not assignable to parameter of type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: number[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unique symbol; }, deriveParamsFromConfig<...>> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<deriveParamsFromConfig<RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>, { projectId: string; }>, deriveParamsFromConfig<...>>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: number[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unique symbol; }, deriveParamsFromConfig<...>>'. Types of property 'unstable_pipe' are incompatible. Type '<$Params extends ProcedureParams<AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; ... 5 more ...; _output_out: unknown; }, $Params> | MiddlewareFunction<....' is not assignable to type '<$Params extends ProcedureParams<AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: number[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, $Par...'. Types of parameters 'fn' and 'fn' are incompatible. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: number[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, any> | MiddlewareFunction<...>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {}; _input_in: { projectId: string; }; _input_out: unique symbol; _output_in: unknown; _output_out: unknown; }, any> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: number[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, any>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {}; _input_in: { projectId: string; }; _input_out: unique symbol; _output_in: unknown; _output_out: unknown; }, any> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: number[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, any>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {}; _input_in: { projectId: string; }; _input_out: unique symbol; _output_in: unknown; _output_out: unknown; }, any>'. The types of 'unstable_pipe(...)._middlewares' are incompatible between these types. Type 'MiddlewareFunction<{ _config: RootConfig<{ ctx: { allowedProjects: number[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, { ...; }>[]' is not assignable to type 'MiddlewareFunction<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {}; _input_in: { projectId: string; }; _input_out: unique symbol; _output_in: unknown; _output_out: unknown; }, { ...; }>[]'. Type 'MiddlewareFunction<{ _config: RootConfig<{ ctx: { allowedProjects: number[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, { ...; }>' is not assignable to type 'MiddlewareFunction<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {}; _input_in: { projectId: string; }; _input_out: unique symbol; _output_in: unknown; _output_out: unknown; }, { ...; }>'. Types of parameters 'opts' and 'opts' are incompatible. Type '{ ctx: { allowedProjects: string[]; }; type: "query" | "mutation" | "subscription"; path: string; input: { projectId: string; }; rawInput: unknown; meta: object | undefined; next: { (): Promise<MiddlewareResult<{ _config: RootConfig<{ ctx: { ...; }; meta: object; errorShape: object; transformer: object; }>; ... 5 mo...' is not assignable to type '{ ctx: { allowedProjects: number[]; }; type: "query" | "mutation" | "subscription"; path: string; input: { projectId: string; }; rawInput: unknown; meta: object | undefined; next: { (): Promise<MiddlewareResult<{ _config: RootConfig<{ ctx: { ...; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDa...'. The types of 'ctx.allowedProjects' are incompatible between these types. Type 'string[]' is not assignable to type 'number[]'.
ts
import {
experimental_standaloneMiddleware,
initTRPC,
TRPCError,
} from '@trpc/server';
import * as z from 'zod';
 
const projectAccessMiddleware = experimental_standaloneMiddleware<{
ctx: { allowedProjects: string[] }; // defaults to 'object' if not defined
input: { projectId: string }; // defaults to 'unknown' if not defined
// 'meta', not defined here, defaults to 'object | undefined'
}>().create((opts) => {
if (!opts.ctx.allowedProjects.includes(opts.input.projectId)) {
throw new TRPCError({
code: 'FORBIDDEN',
message: 'Not allowed',
});
}
 
return opts.next();
});
 
const t1 = initTRPC
.context<{
allowedProjects: string[];
}>()
.create();
 
// ✅ `ctx.allowedProjects` satisfies "string[]" and `input.projectId` satisfies "string"
const accessControlledProcedure = t1.procedure
.input(z.object({ projectId: z.string() }))
.use(projectAccessMiddleware);
 
// ❌ `ctx.allowedProjects` satisfies "string[]" but `input.projectId` does not satisfy "string"
const accessControlledProcedure2 = t1.procedure
.input(z.object({ projectId: z.number() }))
.use(projectAccessMiddleware);
Argument of type 'MiddlewareBuilder<deriveParamsFromConfig<RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>, { projectId: string; }>, deriveParamsFromConfig<...>>' is not assignable to parameter of type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unique symbol; }, deriveParamsFromConfig<...>> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<deriveParamsFromConfig<RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>, { projectId: string; }>, deriveParamsFromConfig<...>>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unique symbol; }, deriveParamsFromConfig<...>>'. Types of property 'unstable_pipe' are incompatible. Type '<$Params extends ProcedureParams<AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; ... 5 more ...; _output_out: unknown; }, $Params> | MiddlewareFunction<....' is not assignable to type '<$Params extends ProcedureParams<AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, $Par...'. Types of parameters 'fn' and 'fn' are incompatible. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, any> | MiddlewareFunction<...>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {}; _input_in: { projectId: string; }; _input_out: unique symbol; _output_in: unknown; _output_out: unknown; }, any> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, any>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {}; _input_in: { projectId: string; }; _input_out: unique symbol; _output_in: unknown; _output_out: unknown; }, any> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, any>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {}; _input_in: { projectId: string; }; _input_out: unique symbol; _output_in: unknown; _output_out: unknown; }, any>'. Types of property 'unstable_pipe' are incompatible. Type '<$Params extends ProcedureParams<AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: any; }, $Params>...' is not assignable to type '<$Params extends ProcedureParams<AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; ... 5 more ...; _output_out: any; }, $Params> | MiddlewareFunction<...>)...'. Types of parameters 'fn' and 'fn' are incompatible. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {} & { [key: string]: any; }; _input_in: { ...; }; _input_out: any; _output_in: any; _output_out: any; }, any> | MiddlewareFunction<...>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: any; }, any> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {} & { [key: string]: any; }; _input_in: { ...; }; _input_out: any; _output_in: any; _output_out: any; }, any>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: any; }, any> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {} & { [key: string]: any; }; _input_in: { ...; }; _input_out: any; _output_in: any; _output_out: any; }, any>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: any; }, any>'. Types of property '_middlewares' are incompatible. Type 'MiddlewareFunction<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {} & { [key: string]: any; }; _input_in: { ...; }; _input_out: any; _output_in: any; _output_out: any; }, any>[]' is not assignable to type 'MiddlewareFunction<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: any; }, any>[]'. Type 'MiddlewareFunction<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {} & { [key: string]: any; }; _input_in: { ...; }; _input_out: any; _output_in: any; _output_out: any; }, any>' is not assignable to type 'MiddlewareFunction<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: any; }, any>'. Types of parameters 'opts' and 'opts' are incompatible. Type '{ ctx: { [x: string]: any; allowedProjects: any; }; type: "query" | "mutation" | "subscription"; path: string; input: { projectId: number; }; rawInput: unknown; meta: object | undefined; next: { (): Promise<MiddlewareResult<{ ...; }>>; <$Context>(opts: { ...; }): Promise<...>; (opts: { ...; }): Promise<...>; }; }' is not assignable to type '{ ctx: { [x: string]: any; allowedProjects: any; }; type: "query" | "mutation" | "subscription"; path: string; input: { projectId: string; }; rawInput: unknown; meta: object | undefined; next: { (): Promise<MiddlewareResult<{ ...; }>>; <$Context>(opts: { ...; }): Promise<...>; (opts: { ...; }): Promise<...>; }; }'. The types of 'input.projectId' are incompatible between these types. Type 'number' is not assignable to type 'string'.2345Argument of type 'MiddlewareBuilder<deriveParamsFromConfig<RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>, { projectId: string; }>, deriveParamsFromConfig<...>>' is not assignable to parameter of type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unique symbol; }, deriveParamsFromConfig<...>> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<deriveParamsFromConfig<RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>, { projectId: string; }>, deriveParamsFromConfig<...>>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unique symbol; }, deriveParamsFromConfig<...>>'. Types of property 'unstable_pipe' are incompatible. Type '<$Params extends ProcedureParams<AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; ... 5 more ...; _output_out: unknown; }, $Params> | MiddlewareFunction<....' is not assignable to type '<$Params extends ProcedureParams<AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, $Par...'. Types of parameters 'fn' and 'fn' are incompatible. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, any> | MiddlewareFunction<...>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {}; _input_in: { projectId: string; }; _input_out: unique symbol; _output_in: unknown; _output_out: unknown; }, any> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, any>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {}; _input_in: { projectId: string; }; _input_out: unique symbol; _output_in: unknown; _output_out: unknown; }, any> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, any>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {}; _input_in: { projectId: string; }; _input_out: unique symbol; _output_in: unknown; _output_out: unknown; }, any>'. Types of property 'unstable_pipe' are incompatible. Type '<$Params extends ProcedureParams<AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: any; }, $Params>...' is not assignable to type '<$Params extends ProcedureParams<AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; ... 5 more ...; _output_out: any; }, $Params> | MiddlewareFunction<...>)...'. Types of parameters 'fn' and 'fn' are incompatible. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {} & { [key: string]: any; }; _input_in: { ...; }; _input_out: any; _output_in: any; _output_out: any; }, any> | MiddlewareFunction<...>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: any; }, any> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {} & { [key: string]: any; }; _input_in: { ...; }; _input_out: any; _output_in: any; _output_out: any; }, any>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: any; }, any> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {} & { [key: string]: any; }; _input_in: { ...; }; _input_out: any; _output_in: any; _output_out: any; }, any>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: any; }, any>'. Types of property '_middlewares' are incompatible. Type 'MiddlewareFunction<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {} & { [key: string]: any; }; _input_in: { ...; }; _input_out: any; _output_in: any; _output_out: any; }, any>[]' is not assignable to type 'MiddlewareFunction<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: any; }, any>[]'. Type 'MiddlewareFunction<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {} & { [key: string]: any; }; _input_in: { ...; }; _input_out: any; _output_in: any; _output_out: any; }, any>' is not assignable to type 'MiddlewareFunction<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: any; }, any>'. Types of parameters 'opts' and 'opts' are incompatible. Type '{ ctx: { [x: string]: any; allowedProjects: any; }; type: "query" | "mutation" | "subscription"; path: string; input: { projectId: number; }; rawInput: unknown; meta: object | undefined; next: { (): Promise<MiddlewareResult<{ ...; }>>; <$Context>(opts: { ...; }): Promise<...>; (opts: { ...; }): Promise<...>; }; }' is not assignable to type '{ ctx: { [x: string]: any; allowedProjects: any; }; type: "query" | "mutation" | "subscription"; path: string; input: { projectId: string; }; rawInput: unknown; meta: object | undefined; next: { (): Promise<MiddlewareResult<{ ...; }>>; <$Context>(opts: { ...; }): Promise<...>; (opts: { ...; }): Promise<...>; }; }'. The types of 'input.projectId' are incompatible between these types. Type 'number' is not assignable to type 'string'.
 
// ❌ `ctx.allowedProjects` does not satisfy "string[]" even though `input.projectId` satisfies "string"
const t2 = initTRPC
.context<{
allowedProjects: number[];
}>()
.create();
 
const accessControlledProcedure3 = t2.procedure
.input(z.object({ projectId: z.string() }))
.use(projectAccessMiddleware);
Argument of type 'MiddlewareBuilder<deriveParamsFromConfig<RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>, { projectId: string; }>, deriveParamsFromConfig<...>>' is not assignable to parameter of type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: number[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unique symbol; }, deriveParamsFromConfig<...>> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<deriveParamsFromConfig<RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>, { projectId: string; }>, deriveParamsFromConfig<...>>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: number[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unique symbol; }, deriveParamsFromConfig<...>>'. Types of property 'unstable_pipe' are incompatible. Type '<$Params extends ProcedureParams<AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; ... 5 more ...; _output_out: unknown; }, $Params> | MiddlewareFunction<....' is not assignable to type '<$Params extends ProcedureParams<AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: number[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, $Par...'. Types of parameters 'fn' and 'fn' are incompatible. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: number[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, any> | MiddlewareFunction<...>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {}; _input_in: { projectId: string; }; _input_out: unique symbol; _output_in: unknown; _output_out: unknown; }, any> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: number[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, any>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {}; _input_in: { projectId: string; }; _input_out: unique symbol; _output_in: unknown; _output_out: unknown; }, any> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: number[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, any>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {}; _input_in: { projectId: string; }; _input_out: unique symbol; _output_in: unknown; _output_out: unknown; }, any>'. The types of 'unstable_pipe(...)._middlewares' are incompatible between these types. Type 'MiddlewareFunction<{ _config: RootConfig<{ ctx: { allowedProjects: number[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, { ...; }>[]' is not assignable to type 'MiddlewareFunction<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {}; _input_in: { projectId: string; }; _input_out: unique symbol; _output_in: unknown; _output_out: unknown; }, { ...; }>[]'. Type 'MiddlewareFunction<{ _config: RootConfig<{ ctx: { allowedProjects: number[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, { ...; }>' is not assignable to type 'MiddlewareFunction<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {}; _input_in: { projectId: string; }; _input_out: unique symbol; _output_in: unknown; _output_out: unknown; }, { ...; }>'. Types of parameters 'opts' and 'opts' are incompatible. Type '{ ctx: { allowedProjects: string[]; }; type: "query" | "mutation" | "subscription"; path: string; input: { projectId: string; }; rawInput: unknown; meta: object | undefined; next: { (): Promise<MiddlewareResult<{ _config: RootConfig<{ ctx: { ...; }; meta: object; errorShape: object; transformer: object; }>; ... 5 mo...' is not assignable to type '{ ctx: { allowedProjects: number[]; }; type: "query" | "mutation" | "subscription"; path: string; input: { projectId: string; }; rawInput: unknown; meta: object | undefined; next: { (): Promise<MiddlewareResult<{ _config: RootConfig<{ ctx: { ...; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDa...'. The types of 'ctx.allowedProjects' are incompatible between these types. Type 'string[]' is not assignable to type 'number[]'.2345Argument of type 'MiddlewareBuilder<deriveParamsFromConfig<RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>, { projectId: string; }>, deriveParamsFromConfig<...>>' is not assignable to parameter of type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: number[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unique symbol; }, deriveParamsFromConfig<...>> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<deriveParamsFromConfig<RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>, { projectId: string; }>, deriveParamsFromConfig<...>>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: number[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unique symbol; }, deriveParamsFromConfig<...>>'. Types of property 'unstable_pipe' are incompatible. Type '<$Params extends ProcedureParams<AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; ... 5 more ...; _output_out: unknown; }, $Params> | MiddlewareFunction<....' is not assignable to type '<$Params extends ProcedureParams<AnyRootConfig, unknown, unknown, unknown, unknown, unknown, unknown>>(fn: MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: number[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, $Par...'. Types of parameters 'fn' and 'fn' are incompatible. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: number[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, any> | MiddlewareFunction<...>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {}; _input_in: { projectId: string; }; _input_out: unique symbol; _output_in: unknown; _output_out: unknown; }, any> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: number[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, any>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {}; _input_in: { projectId: string; }; _input_out: unique symbol; _output_in: unknown; _output_out: unknown; }, any> | MiddlewareFunction<...>'. Type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: number[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, any>' is not assignable to type 'MiddlewareBuilder<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {}; _input_in: { projectId: string; }; _input_out: unique symbol; _output_in: unknown; _output_out: unknown; }, any>'. The types of 'unstable_pipe(...)._middlewares' are incompatible between these types. Type 'MiddlewareFunction<{ _config: RootConfig<{ ctx: { allowedProjects: number[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, { ...; }>[]' is not assignable to type 'MiddlewareFunction<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {}; _input_in: { projectId: string; }; _input_out: unique symbol; _output_in: unknown; _output_out: unknown; }, { ...; }>[]'. Type 'MiddlewareFunction<{ _config: RootConfig<{ ctx: { allowedProjects: number[]; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDataTransformer; }>; ... 5 more ...; _output_out: unknown; }, { ...; }>' is not assignable to type 'MiddlewareFunction<{ _config: RootConfig<{ ctx: { allowedProjects: string[]; }; meta: object; errorShape: object; transformer: object; }>; _meta: object; _ctx_out: {}; _input_in: { projectId: string; }; _input_out: unique symbol; _output_in: unknown; _output_out: unknown; }, { ...; }>'. Types of parameters 'opts' and 'opts' are incompatible. Type '{ ctx: { allowedProjects: string[]; }; type: "query" | "mutation" | "subscription"; path: string; input: { projectId: string; }; rawInput: unknown; meta: object | undefined; next: { (): Promise<MiddlewareResult<{ _config: RootConfig<{ ctx: { ...; }; meta: object; errorShape: object; transformer: object; }>; ... 5 mo...' is not assignable to type '{ ctx: { allowedProjects: number[]; }; type: "query" | "mutation" | "subscription"; path: string; input: { projectId: string; }; rawInput: unknown; meta: object | undefined; next: { (): Promise<MiddlewareResult<{ _config: RootConfig<{ ctx: { ...; }; meta: object; errorShape: DefaultErrorShape; transformer: DefaultDa...'. The types of 'ctx.allowedProjects' are incompatible between these types. Type 'string[]' is not assignable to type 'number[]'.

这是一个包含多个独立中间件的示例:

¥Here is an example with multiple standalone middlewares:

ts
import { experimental_standaloneMiddleware, initTRPC } from '@trpc/server';
import * as z from 'zod';
 
const t = initTRPC.create();
const schemaA = z.object({ valueA: z.string() });
const schemaB = z.object({ valueB: z.string() });
 
const valueAUppercaserMiddleware = experimental_standaloneMiddleware<{
input: z.infer<typeof schemaA>;
}>().create((opts) => {
return opts.next({
ctx: { valueAUppercase: opts.input.valueA.toUpperCase() },
});
});
 
const valueBUppercaserMiddleware = experimental_standaloneMiddleware<{
input: z.infer<typeof schemaB>;
}>().create((opts) => {
return opts.next({
ctx: { valueBUppercase: opts.input.valueB.toUpperCase() },
});
});
 
const combinedInputThatSatisfiesBothMiddlewares = z.object({
valueA: z.string(),
valueB: z.string(),
extraProp: z.string(),
});
 
t.procedure
.input(combinedInputThatSatisfiesBothMiddlewares)
.use(valueAUppercaserMiddleware)
.use(valueBUppercaserMiddleware)
.query(
({
input: { valueA, valueB, extraProp },
ctx: { valueAUppercase, valueBUppercase },
}) =>
`valueA: ${valueA}, valueB: ${valueB}, extraProp: ${extraProp}, valueAUppercase: ${valueAUppercase}, valueBUppercase: ${valueBUppercase}`,
);
ts
import { experimental_standaloneMiddleware, initTRPC } from '@trpc/server';
import * as z from 'zod';
 
const t = initTRPC.create();
const schemaA = z.object({ valueA: z.string() });
const schemaB = z.object({ valueB: z.string() });
 
const valueAUppercaserMiddleware = experimental_standaloneMiddleware<{
input: z.infer<typeof schemaA>;
}>().create((opts) => {
return opts.next({
ctx: { valueAUppercase: opts.input.valueA.toUpperCase() },
});
});
 
const valueBUppercaserMiddleware = experimental_standaloneMiddleware<{
input: z.infer<typeof schemaB>;
}>().create((opts) => {
return opts.next({
ctx: { valueBUppercase: opts.input.valueB.toUpperCase() },
});
});
 
const combinedInputThatSatisfiesBothMiddlewares = z.object({
valueA: z.string(),
valueB: z.string(),
extraProp: z.string(),
});
 
t.procedure
.input(combinedInputThatSatisfiesBothMiddlewares)
.use(valueAUppercaserMiddleware)
.use(valueBUppercaserMiddleware)
.query(
({
input: { valueA, valueB, extraProp },
ctx: { valueAUppercase, valueBUppercase },
}) =>
`valueA: ${valueA}, valueB: ${valueB}, extraProp: ${extraProp}, valueAUppercase: ${valueAUppercase}, valueBUppercase: ${valueBUppercase}`,
);