我正在尝试输入名为
route
的函数。我在我的 Express 项目中使用它
const morph = (params: Function[]) => (req: Request) => params.map(f => f(req))
const applyTransformers = (transformers: Function[]) => (response: any) => {
for (const transformer in transformers) {
response = transformer(response)
}
return response
}
export const route = <
H extends (...args: any[]) => Promise<any>,
T extends any[] = Parameters<H>,
P extends Function[] = { [K in keyof T]: (req?: Request) => T[K] }
>(handler: H, params: P = [] as P, transformers: Function[] = []): RequestHandler | ErrorRequestHandler => (
wrap(
async (req: Request, res: Response) => {
// eslint-disable-next-line no-debugger
// debugger
const result = await handler(
...morph(params)(req)
)
res.send(applyTransformers(transformers)(result))
}
)
)
// Usage:
// id = (req: Request): string => req.params.id
// customParam = (param: string) => (req: Request): string => req.params[param]
// ...
// app.get('/example-route/:id/blah/:blah', route(handler, [id, customParam('blah')])
// handler: (string, string) => Promise<any>
问题如下: 我不想在使用路由函数时为其提供泛型类型。我希望它理解
handler
和 params
的类型“匹配”,如果它们不“匹配”,我想得到一个 TypeError。但它并没有按预期工作。例如,如果 handler
的类型为 (string, number) => Promise<any>
并且 params
的类型为 [(Request) => number, (Request) => string]
TypeScript 不会给我错误。
我对原始代码进行了一些重构,但这个具体示例的解决方案是使泛型类型 P 扩展它所分配的类型。那就是替换
P extends Function[] = { [K in keyof T]: (req?: Request) => T[K] }
与
P extends { [K in keyof T]: (req?: Request) => T[K] } = { [K in keyof T]: (req?: Request) => T[K] }
这样代码看起来像:
export const route = <
H extends (...args: any[]) => Promise<any>,
T extends any[] = Parameters<H>,
P extends { [K in keyof T]: (req?: Request) => T[K] } = { [K in keyof T]: (req?: Request) => T[K] }
>(handler: H, params: P = [] as P, transformers: Function[] = []): RequestHandler | ErrorRequestHandler => (
wrap(
async (req: Request, res: Response) => {
// eslint-disable-next-line no-debugger
// debugger
const result = await handler(
...morph(params)(req)
)
res.send(applyTransformers(transformers)(result))
}
)
)