Расширить объект Express Request с помощью TypScript

Я пытаюсь добавить свойство для выражения объекта запроса из промежуточного программного обеспечения с помощью машинописного текста. Однако я не могу понять, как добавить дополнительные объекты к объекту. Я предпочел бы, если возможно, использовать нотацию с кронштейнами.

Я ищу решение, которое позволило бы мне написать что-то похожее на это (если возможно):

app.use((req, res, next) => { req.property = setProperty(); next(); }); 

    В TypeScript интерфейсы открыты. Это означает, что вы можете добавлять к ним свойства из любого места, просто переопределяя их.

    Учитывая, что вы используете этот файл express.d.ts , вы должны переопределить интерфейс Request, чтобы добавить дополнительное поле.

     interface Request { property: string; } 

    Затем в вашей функции промежуточного программного обеспечения параметр req должен также иметь это свойство. Вы можете использовать его без каких-либо изменений в коде.

    Вы хотите создать собственное определение и использовать функцию в машинописном названии « Слияние слияния» . Это обычно используется, например, в method-override .

    Создайте файл custom.d.ts и обязательно custom.d.ts его в files tsconfig.json если они есть. Содержимое может выглядеть следующим образом:

     declare namespace Express { export interface Request { tenant?: string } } 

    Это позволит вам в любой момент вашего кода использовать что-то вроде этого:

     router.use((req, res, next) => { req.tenant = 'tenant-X' next() }) router.get('/whichTenant', (req, res) => { res.status(200).send('This is your tenant: '+req.tenant) }) 

    Вы просто объявляете глобальное пространство имен Express любым новым членам. Пример:

     declare global { namespace Express { interface Request { context: Context } } } 

    Полный пример:

     import * as express from 'express'; export class Context { constructor(public someContextVariable) { } log(message: string) { console.log(this.someContextVariable, { message }); } } declare global { namespace Express { interface Request { context: Context } } } const app = express(); app.use((req, res, next) => { req.context = new Context(req.url); next(); }); app.use((req, res, next) => { req.context.log('about to return') res.send('hello world world'); }); app.listen(3000, () => console.log('Example app listening on port 3000!')) 

    Больше

    Расширение глобальных пространств имен описано здесь: https://basarat.gitbooks.io/typescript/docs/types/lib.d.ts.html

    Мои 2 цента: Расширьте текущий тип и код, как обычно.

     import { Request, Response, Router } from 'express' function handler(req: IRequest, res: Response, next: Function) { const authId = req.authId // ... } const router = Router() router.get('/', handler) // no compiling problems // this is just for ts, will disappear in transpilation interface IRequest extends Request { authId: string // example } 

    Одним из возможных решений является использование «двойного литья в любой»,

    1- определить интерфейс с вашим свойством

     export interface MyRequest extends http.IncomingMessage { myProperty: string } 

    2- двойное литье

     app.use((req: http.IncomingMessage, res: http.ServerResponse, next: (err?: Error) => void) => { const myReq: MyRequest = req as any as MyRequest myReq.myProperty = setProperty() next() }) 

    Преимущества двойного литья заключаются в следующем:

    • доступны тиски
    • он не загрязняет существующие определения, а расширяет их, избегая путаницы
    • поскольку литье является явным, оно компилирует штрафы с флагом -noImplicitany

    Кроме того, существует быстрый (нетипизированный) маршрут:

      req['myProperty'] = setProperty() 

    (не редактируйте существующие файлы определений со своими собственными свойствами – это недопустимо. Если определения неверны, откройте запрос на перенос)

    РЕДАКТИРОВАТЬ

    См. Комментарий ниже, простые кастинговые работы в этом случае req as MyRequest

    Ни один из предлагаемых решений не работал для меня. В итоге я просто расширил интерфейс Request:

     import {Request} from 'express'; export interface RequestCustom extends Request { property: string; } 

    Затем, чтобы использовать его:

     import {NextFunction, Response} from 'express'; import {RequestCustom} from 'RequestCustom'; someMiddleware(req: RequestCustom, res: Response, next: NextFunction): void { req.property = ''; } 

    Принимаемый ответ (как и другие) не работает для меня, но

     declare module 'express' { interface Request { myProperty: string; } } 

    сделал. Надеюсь, что это поможет кому-то.

    Давайте будем гением компьютера.