【发布时间】:2021-08-10 03:33:12
【问题描述】:
我可以很容易地在 typescript 中扩展 express.Request,例如:
interface MyRequest extends express.Request {
userId: string;
}
但是,如果我编写一个使用它的中间件函数,例如:
const myMiddlewareFn = (req: MyRequest, res: express.Response) => {
req.userId; // <-- this works as a string
}
app.get('/user', myMiddlewareFn) // <-- this does NOT type-check because MyRequest is more narrow than express.Request.
我看到很多关于如何扩展 express.Request 的讨论。我怎样才能在我的路线中正确地进行类型检查?
目前我正在做这样的事情:
/**
* @param allowedRoles see HasuraCustomClaims
* @param handlerFn the final business logic
* @returns an array of middleware, correctly typed for the handlerFn
*/
export function addApiAuthMiddleware(
allowedRoles: string[],
...handlerFns: (
| ((req: OTApiAuthorizedRequest, res: Response) => Promise<void>)
| ((req: OTApiValidatedAndAuthorizedRequest<any>, res: Response) => Promise<void>)
)[]
): express.RequestHandler[] {
return [
decodeIdToken,
guardRequestHandler(createRoleAuthMiddleware(allowedRoles)),
...handlerFns.map((handlerFn) => guardRequestHandler(handlerFn)),
];
}
/**
* This typecasting is a *little* jank.
*
* @param middlewareOrHandlerFn either api middleware or a final api handler function
* @returns
*/
export function guardRequestHandler<T extends Request>(
middlewareOrHandlerFn:
| ((req: T, res: Response, next: express.NextFunction) => Promise<void>)
| ((req: T, res: Response) => Promise<void>),
): express.RequestHandler {
return (middlewareOrHandlerFn as unknown) as express.RequestHandler;
}
// this below type-checks
app.get('/user', ...addApiAuthMiddleware(['admin'], userHandlerFn));
有没有更好的办法?
【问题讨论】:
标签: node.js typescript express