[Typescript] Creating Chainable Method Abstractions with Generics and the Builder Pattern - 05
import { expect, it } from "vitest";
import { fetchUser } from "fake-external-lib";
type Middleware<TInput, TOutput> = (input: TInput) => TOutput;
class DynamicMiddleware<TInput, TOutput> {
private middleware: Middleware<any, any>[] = [];
constructor(firstMiddleware: Middleware<TInput, TOutput>) {
this.middleware.push(firstMiddleware);
}
// use middleware, the input should be previous step's output
// the output of the middleware should be new, using genric
// the outptu of the middleware will be the input of next middleware
use<NewTOutput>(
middleware: Middleware<TOutput, NewTOutput>
): DynamicMiddleware<TInput, NewTOutput> {
this.middleware.push(middleware);
return this as any;
}
async run(input: TInput): Promise<TOutput> {
let result: TOutput = input as any;
for (const middleware of this.middleware) {
result = await middleware(result);
}
return result;
}
}
const middleware = new DynamicMiddleware((req: Request) => {
return {
...req,
userId: req.url.split("/")[2],
};
})
.use((req) => {
if (req.userId === "123") {
throw new Error();
}
return req;
})
.use(async (req) => {
return {
...req,
user: await fetchUser(req.userId),
};
});
it("Should fail if the user id is 123", () => {
expect(middleware.run({ url: "/user/123" } as Request)).rejects.toThrow();
});
it("Should return a request with a user", async () => {
const result = await middleware.run({ url: "/user/matt" } as Request);
expect(result.user.id).toBe("matt");
expect(result.user.firstName).toBe("John");
expect(result.user.lastName).toBe("Doe");
});
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2021-02-15 [Node] Install packages correctly and avoid attacks
2020-02-15 【时间管理】猴子理论 ”monkey-on-the-back” Analogy
2020-02-15 【时间管理】GTD:Getting things done
2019-02-15 [Webpack] Create Separate webpack Configs for Development and Production with webpack-merge
2019-02-15 [Algorithm] Reverse array of Chars by word
2018-02-15 [Tools] Using mobile device for debugging your mobile web site
2018-02-15 [Tools] Create your own mobile emulator device by using Chrome dev tool