我必須繼續做類似的事情
if (!req.user) return res.status(401).send()
想到的方法將是一個快速的中間件。但即使我可以阻止非登錄用戶到達路線,我也想不出正確輸入 express req的方法。
如果我覆寫“ req ”引數,路由器會抱怨,因為“ Express.User ”中的用戶鍵是可選引數。
我不相信更改全域覆寫因此需要“ user ”是一個不錯的選擇,因為只有在中間件驗證之后才需要“ user ”。我怎樣才能做到這一點?
下面是一些有用的代碼來理解背景關系。
全球快遞覆寫
declare global {
namespace Express {
interface User extends TUser {
_id: ObjectId
}
}
}
我想要達到的目標
// Router
router.post('/', sessionMiddleware, controller)
// Middleware
const sessionMiddleware = (req: Request, res: Response, next: NextFunction) => {
if (!req.user) return res.status(401).send()
next()
}
// Controller
const controller = (req: RequestWithRequiredUser, res: Response) => {
// user here can't possibly be typed undefined
const user = req.user
...
}
我實際上每次都要做的事情:
const controller = (req: Request, res: Response) => {
if (!req.user) return res.status(401).send()
...doSomethingElse
}
uj5u.com熱心網友回復:
如果有更好的中間件解決方案,我不知道,但這是我發現的一種解決方法,可以避免重復邏輯。
構建會話控制器.ts
/** Make given keys required */
export type WithRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] }
type TController<T extends Request> = (req: WithRequired<T, 'user'>, res: Response) => unknown
export const buildSessionController =
<T extends Request>(controller: TController<T>) =>
(req: Request, res: Response) => {
if (!req.user) return res.status(401).send()
// This is needed as a type workaround because a type mismatch happens otherwise
// Using Omit instead of WithRequired above doesn't fix it
const request = req as WithRequired<T, 'user'>
return controller(request, res)
}
一些控制器.ts
export const expressController =
buildSessionController((req, res) => {
// user will never be undefined here
const { user } = req
return res.json(user)
})
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/512463.html
