typescript / expert
Snippet
Variadic Tuple Inference for Type-Safe Middleware Pipelines
This design demonstrates how async middleware composition can be typed in framework engines. Using functional recursive iteration with next handlers ensures controlled contextual transformations across asynchronous operations.
snippet.ts
typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
type Middleware<TContext> = (ctx: TContext, next: () => Promise<void>) => Promise<void>;class Pipeline<TContext> {private middlewares: Middleware<TContext>[] = [];use(...fns: Middleware<TContext>[]): this {this.middlewares.push(...fns);return this;}async execute(ctx: TContext): Promise<void> {const runner = async (index: number): Promise<void> => {if (index >= this.middlewares.length) return;const mw = this.middlewares[index];await mw(ctx, () => runner(index + 1));};await runner(0);}}interface HttpContext { reqId: string; status?: number; }const pipeline = new Pipeline<HttpContext>().use(async (ctx, next) => {ctx.status = 200;await next();});
Breakdown
1
type Middleware<TContext> = (ctx: TContext, next: () => Promise<void>) => Promise<void>;
Specifies a strongly typed middleware handler contract accepting context and a downstream next executor.
2
use(...fns: Middleware<TContext>[]): this
Enables chainable registration using variadic parameter gathering constrained to valid middleware signatures.
3
const runner = async (index: number): Promise<void> => {
Encapsulates internal recursive execution pointer over stored middleware functions.
4
await mw(ctx, () => runner(index + 1));
Passes control to the next middleware in sequence when the user calls next().