[Typescript] Creating Chainable Method Abstractions with Generics and the Builder Pattern - 05
typescript The and with 05 method pattern Builder
2023-09-14 08:59:11 时间
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");
});
相关文章
- Typescript 4.9重点特性探索
- typeScript 全局库 文件声明
- 快速搭建基于Vue3+Vite2+Arco+Typescript+Pinia后台管理系统模板,文末有福利
- 快速掌握 TypeScript 新语法:infer extends
- 【踩坑实录】-java.sql.SQLException: The MySQL server is running with the LOCK_WRITE_GROWTH option so it ca
- Flow 与 Typescript:哪个更适合你的项目?
- 解决 Typescript 文件被识别为视频的问题
- typescript error TS2322: Type ‘Timeout‘ is not assignable to type ‘number‘.
- Vue 3 + Typescript + Vite 基个人网站二维码登录功能
- 软件开发入门教程网之TypeScript 声明文件
- 深入学习下 TypeScript 中的泛型
- (一)为什么要使用 TypeScript(二)安装并配置 Ts
- Webpack搭建简单的TypeScript脚手架
- 【错误记录】Flutter 编译报错 ( The parameter ‘‘ can‘t have a value of ‘null‘ because of its type, but the im )
- 开心档之TypeScript 变量声明
- django2 The custom handler404 view 'users.views.page_not_found' does not take the correct number of
- ORA-28077: The attribute specified (string) exceeds the maximum length. ORACLE 报错 故障修复 远程处理
- ORA-28085: The input and output lengths of the redaction do not match. ORACLE 报错 故障修复 远程处理
- ORA-32019: The parameter SPFILE cannot be updated in the server parameter file. ORACLE 报错 故障修复 远程处理
- ORA-48444: The single “.” and “*” cannot appear in the middle of the path ORACLE 报错 故障修复 远程处理
- ORA-53253: The metadata for the new DICOM object is invalid. ORACLE 报错 故障修复 远程处理
- ORA-13619: The procedure argument string is greater than the maximum allowable length of string characters. ORACLE 报错 故障修复 远程处理
- ORA-13632: The user cancelled the current operation. ORACLE 报错 故障修复 远程处理
- ORA-13904: The file has been dropped and recreated during the procedure call. ORACLE 报错 故障修复 远程处理
- The Power of Linux: Unleashing the Potential of OpenSource Software(linux英文)
- Exploring the Power of MongoDB: The Definitive Guide to Upgrading Arrays(mongodb更新数组)