node.js - نمیتوان به هدرها در نوع گسترشیافته Express.Request دسترسی پیدا کرد
من در حال تلاش برای گسترش Request در Express هستم تا دقیقاً نوعی را تعریف کنم که یک query چگونه خواهد بود. در حال حاضر این کار را به صورت زیر انجام میدهم:
export interface TypedRequestQuery<T> extends Express.Request {
query: T;
}
این بیشتر اوقات کار میکند، اما به نظر میرسد برخی خصوصیات تعریف نشدهاند. به عنوان مثال:
(req as TypedRequestQuery<{data: string}>).headers
کار نمیکند. این منجر به خطای زیر میشود:
Property 'headers' does not exist on type 'TypedRequestQuery<{ data: string; }>'
من در منابع مختلف خواندهام که Express.Request نوع صحیح برای آرگومان request یک هندلر درخواست است. اما شاید من اشتباه فهمیدهام؟ کنار گذاشتن تایپهای هندلر درخواست هم کار میکند!
router.get("/", async (req, res) => {
req.headers["x-forwarded-for"] // no errors
})
و ویژگی headers در req وجود دارد.
من از passport.js استفاده میکنم که متوجه شدهام تعریف Request را تغییر میدهد (یا حداقل آن را توسعه میدهد). مطمئن نیستم که این دلیل باشد.
سؤال من این است: آیا Express.Request نوع درستی است که از آن در اینجا توسعه دهیم؟ اگر هست، چرا این رابط به نظر ناقص میرسد و چگونه میتوانم این مشکل را رفع کنم؟ اگر نیست، از چه نوعی باید توسعه دهیم؟
پاسخ شماره ۱
نوع درخواست Express قبلاً به شما امکان میدهد نوع پرسوجو را تعریف کنید...
export interface Request<
P = ParamsDictionary,
ResBody = any,
ReqBody = any,
ReqQuery = ParsedQs, // 👈
Locals extends Record<string, any> = Record<string, any>
> ...
نوع پرسوجو، چهارمین نوع عمومی است، بنابراین شما باید مقادیر پیشفرض برای سه نوع اول ارائه دهید
import { ParamsDictionary, Request } from "express-serve-static-core";
type TypedRequestQuery<
TQuery,
TParams = ParamsDictionary,
TResBody = any,
TReqBody = any
> = Request<TParams, TResBody, TReqBody, TQuery>;
سپس میتوانید از آن در مسیرهای خود استفاده کنید
router.get("/", async (req: TypedRequestQuery<{data: string}>, res) => {
console.log("headers[x-forwarded-for]:", req.headers["x-forwarded-for"]);
console.log("query[data]:", req.query.data);
res.send("I wish Typescript would let us skip generics");
})
مثال شما کامپایل نمیشود زیرا شما در حال تلاش برای بازنویسی ویژگی query با نوع ناسازگار هستید
error TS2430: Interface 'TypedRequestQuery<T>' incorrectly extends interface 'Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>'. Types of property 'query' are incompatible. Type 'T' is not assignable to type 'ParsedQs'. interface TypedRequestQuery<T> extends Request { ~~~~~~~~~~~~~~~~~ interface TypedRequestQuery<T> extends Request { ~ This type parameter might need an `extends ParsedQs` constraint.
یک نسخه سازگار نیاز دارد که نوع پرسوجوی شما ParsedQs را گسترش دهد
import { Request } from "express-serve-static-core";
import { ParsedQs } from "qs"
interface TypedRequestQuery<T extends ParsedQs> extends Request {
query: T;
}
