Typescript - Создание пользовательского экспресс-определения промежуточного программного обеспечения - PullRequest
0 голосов
/ 08 октября 2019

Мне было очень трудно определить пользовательское промежуточное ПО для нашего приложения. Я использую 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). Когда я пытаюсь набрать его таким образом, я получаю разные, но схожие ошибки типа.

Кто-нибудь еще испытывал подобное?

1 Ответ

0 голосов
/ 10 октября 2019

Вы не можете добавить обязательное поле в переменную req и res, потому что express не может удовлетворить ограничение для вас. Кроме того, express не обрабатывает изменение типа req / res после прохождения через другое промежуточное ПО. Таким образом, ваш пользовательский тип может содержать обязательные поля, такие же, как в ExpressRequest / ExpressResponse, остальные поля должны быть необязательными и иметь проверку на нулевое значение внутри промежуточного программного обеспечения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...