Мне было очень трудно определить пользовательское промежуточное ПО для нашего приложения. Я использую typescript@3.6.3 и express@4.17.1.
Все примеры, которые я видел для ввода промежуточного программного обеспечения, подразумевают, что пользователь ничего не добавляет к req
или res
аргумент, но я знаю, что это была своего рода точка промежуточного программного обеспечения - мутируйте любой из этих объектов, зная, что промежуточное программное обеспечение должно быть загружено в определенном порядке (т. е. cookie-parser или body-parser были печально известны в началедни, я думаю, все еще есть?). Как бы то ни было, большинство примеров приводят к подобной проблеме github: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/26146#issuecomment-393386416
Проблема, с которой я столкнулся, заключается в том, что мы мутируем объекты req
и res
, передаваемые каждому промежуточному программному обеспечению. поэтому мне пришлось ввести оба объекта соответственно:
import {
Express as ExpressInterface,
Request as ExpressRequest,
Response as ExpressResponse,
NextFunction as ExpressNextFunction,
} from 'express';
import LoggerType from 'some-log-package';
// don't do anything different the `next()`
export type ExpressNextFunction = ExpressNextFunction;
export interface CustomServerApp extends ExpressInterface {
customHeader: string;
customLogger: LoggerType;
}
export interface CustomServerRequest extends ExpressRequest {
app: CustomServerApp,
id: string,
urlSearchParams: URLSearchParams,
// etc
}
export interface CustomServerResponse extends ExpressResponse { ... }
Итак, я экспортирую основные аргументы для промежуточного программного обеспечения:
req
= CustomServerRequest
res
= CustomServerResponse
next
= ExpressNextFunction
Конечно, я импортирую их соответственно в файлы промежуточного программного обеспечения:
import {
CustomServerRequest,
CustomServerResponse,
ExpressNextFunction
} from './server-types'
export const customMiddleware = (req: CustomServerRequest, res: CustomServerResponse, next: ExpressNextFunction): void {
// do something here with either `req` or `res` or both!
next()
};
У нас есть централизованный middleware.ts
файл, в который мы помещаем все наше глобальное промежуточное программное обеспечение, поэтому он выглядит примерно так:
import { CustomServerApp } from './server-types';
import { customMiddleware } from './middlewares/customMiddleware';
export const middlewares = (app: CustomServerApp): void => {
app.use(
customMiddleware,
// maybe more middlewares, etc
);
}
Однако, когда запускается программа проверки типов, я получаю ошибки, подобные следующим:
No overload matches this call.
The last overload gave the following error.
Argument of type '(req: Request, res: Response, next: NextFunction) => void' is not assignable to parameter of type 'PathParams'.
Type '(req: Request, res: Response, next: NextFunction) => void' is missing the following properties from type '(string | RegExp)[]': pop, push, concat, join, and 27 more.ts(2769)
Мне очень тяжело было понять, почему это учитывается в последнем определении перегрузки. Просто основываясь на @types/express
, кажется, трудно добавить дополнительную перегрузку в обработчик промежуточного программного обеспечения даже при объединении объявлений типов.
Даже если я использую шаблон, аналогичный базовым типам Express, для определения обработчика промежуточного программного обеспечения - https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/express-serve-static-core/index.d.ts#L40-L43 - это тоже не сработает. Также не похоже, что просто набрать extend
из любого - https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/express/index.d.ts#L99 - поскольку вы не можете передать универсальный элемент в RequestHandler ядра, в отличие от определений маршрутизатора (IRouterHandler
, IRouterMatcher
). Когда я пытаюсь набрать его таким образом, я получаю разные, но схожие ошибки типа.
Кто-нибудь еще испытывал подобное?