diff --git a/packages/effect/src/middleware.test-d.ts b/packages/effect/src/middleware.test-d.ts index b57ad17e4..105d14f0e 100644 --- a/packages/effect/src/middleware.test-d.ts +++ b/packages/effect/src/middleware.test-d.ts @@ -105,6 +105,75 @@ describe('middlewareGen', () => { void procedure }) + it('infers everything without type arguments when created via os.middleware', () => { + interface ServerContext extends WithEffectContext { + auth: boolean + } + + const requireAuth = os + .$context() + .middleware(middlewareGen(function* ({ context, next }) { + expectTypeOf(context.auth).toEqualTypeOf() + yield* Service1 + + return yield* next({ context: { user: 'user' as const } }) + })) + + const procedure = os + .$context() + .input(z.object({ id: z.string() })) + .output(z.string()) + .use(requireAuth) + .handler(({ context }) => { + expectTypeOf(context.user).toEqualTypeOf<'user'>() + + return 'output' + }) + + void procedure + }) + + it('supports standalone middleware on procedures with concrete input/output', () => { + interface ServerContext extends WithEffectContext { + auth: boolean + } + + const requireAuth = middlewareGen( + function* ({ context, next }) { + expectTypeOf(context.auth).toEqualTypeOf() + yield* Service1 + + return yield* next({ context: { user: 'user' as const } }) + }, + ) + + const procedure = os + .$context() + .input(z.object({ id: z.string() })) + .output(z.string()) + .use(requireAuth) + .handler(({ context }) => { + expectTypeOf(context.user).toEqualTypeOf<'user'>() + + return 'output' + }) + + void procedure + + const decorated = os + .$context() + .middleware(requireAuth) + + const decoratedProcedure = os + .$context() + .input(z.object({ id: z.string() })) + .output(z.string()) + .use(decorated) + .handler(() => 'output') + + void decoratedProcedure + }) + it('can infer typed errors through os.middleware', () => { // Unlike `.use`, `os.middleware` types `errors` from the builder's error map // because its middleware parameter references the error map non-generically. diff --git a/packages/effect/src/middleware.ts b/packages/effect/src/middleware.ts index e0c2ec9dc..a1e14ce04 100644 --- a/packages/effect/src/middleware.ts +++ b/packages/effect/src/middleware.ts @@ -50,11 +50,11 @@ export type AnyMiddlewareGen = MiddlewareGen */ export function middlewareGen< TInContext extends Context, - TInput, - TOutput, - TErrorMap extends ErrorMap, - TYield extends Effect.Effect>, TOutContext extends Context = object, + TInput = unknown, + TOutput = any, // TOutput = any by default is important to make middleware can be used in any output by default + TErrorMap extends ErrorMap = Record, + TYield extends Effect.Effect> = Effect.Effect>, >( middleware: MiddlewareGen>, ): Middleware {