Typescript Ошибка: свойство 'user' не существует в типе 'Request'

У меня есть следующий фрагмент кода в моем экспресс-приложении

router.get('/auth/userInfo', this.validateUser,  (req, res) => {
    res.json(req.user);
});

и моя IDE, похоже, жалуется на ошибку

error TS2339: Свойство 'user' не существует в типе 'Request'.

Когда я компилирую код typescript, он, кажется, бросает эту ошибку. Есть идеи, почему это происходит?

Ответ 1

У нас есть большой API, написанный в Express и Typescript, и так мы обрабатываем такие сценарии:

Мы сохраняем определения запросов в одном файле:

import { Request } from "express"
export interface IGetUserAuthInfoRequest extends Request {
  user: string // or any other type
}

И затем в файле, где мы пишем функции контроллера:

import { Response } from "express"
import { IGetUserAuthInfoRequest } from "./definitionfile"

app.get('/auth/userInfo', validateUser,  (req: IGetUserAuthInfoRequest, res: Response) => {
  res.status(200).json(req.user); // Start calling status function to be compliant with Express 5.0
});

Обратите внимание, что "пользователь" не является свойством, которое доступно изначально в объекте "Запрос" Express. Убедитесь, что вы используете промежуточное программное обеспечение, которое добавляет такое свойство в объект запроса.

Ответ 2

req, вероятно, имеет тип Request из пакета "express", и пользователь там не существует. Вы должны либо расширить Request с помощью собственного обработчика маршрутизатора, либо привести его к типу any или object.

попробуйте res.json(req['user']) или res.json( (<any>req).user )

Вы также можете использовать модуль/глобальное увеличение

import { Request } from "express"

declare module "express" { 
  export interface Request {
    user: any
  }
}

Вы также можете создать свою собственную оболочку обработчика (вместо расширения функциональности Router в ExpressJs).

import * as express from 'express';

interface IUserRequest extends express.Request {
    user: any
}

function myHandler(handler: (req: IUserRequest, res: express.Response, next?: express.NextFunction) => any) {
    return (req: express.Request, res: express.Response, next: express.NextFunction) => {
        try {

            validateUser(req, res, (err) => { // your validateUser handler that makes a user property in express Request
                if(err)
                     throw err;

                let requestWrapper: IUserRequest = <IUserRequest>req;

                handler(requestWrapper, res, next);
            })                
        }
        catch (ex) {
            next(ex);
        }
    } 
}

let app = express();
// init stuff for express but this.validateUser handler is not needed

app.use('/testuser', myHandler((req, res) => {
    res.json(req.user);
}));

Ответ 3

Вы получаете эту ошибку, потому что нет определения типа для свойства user в собственном объекте express Request. Вам следует установить определения типов для промежуточного программного обеспечения, которое вы используете для добавления user в запрос.

Например, если вы используете библиотеку passport для аутентификации JWT в качестве промежуточного программного обеспечения:

router.get('/auth/userInfo', passport.authenticate('jwt', {session:false}), (req, res, next) => {
  // Get their info from the DB and return it
  User.findOne({ email: req.user.email }, (err, user) => {
    if (err) {return next(err);}
    ...
    ...

Вы должны добавить определения типов для passport:

npm install --save @types/passport