Невозможно расширить экспресс-запрос в TypeScript - PullRequest
0 голосов
/ 04 января 2019

Этот вопрос задавался несколько раз, но ни один из ответов, которые были даны, не помог мне.Я пытаюсь расширить объект Express Request, включив в него свойство для хранения объекта User.Я создал файл объявления express.d.ts и поместил его в тот же каталог, в котором находится мой tsconfig.json:

import { User } from "./src/models/user";

declare namespace Express {
    export interface Request {
        user: User;
    }
}

Затем я пытаюсь сделать ему присвоение в secured-api.ts:

import express from 'express';
import { userService } from '../services/user';

router.use(async (req, res, next) => {
    try {
        const user = await userService.findByUsername(payload.username);

        // do stuff to user...

        req.user = user;
        next();
    } catch(err) {
        // handle error
    }
});

Я получаю следующую ошибку:

src/routes/secured-api.ts:38:21 - error TS2339: Property 'user' does not exist on type 'Request'.

38                 req.user = user;
                       ~~~~

Мой User класс:

import { Model, RelationMappings } from 'objection';

export class User extends Model {

    public static tableName = 'User';
    public static idColumn = 'username';

    public static jsonSchema = {
        type: 'object',
        required: ['fname', 'lname', 'username', 'email', 'password'],

        properties: {
            fname: { type: 'string', minLength: 1, maxLength: 30 },
            lname: { type: 'string', minLength: 1, maxLength: 30 },
            username: { type: 'string', minLength: 1, maxLength: 20 },
            email: { type: 'string', minLength: 1, maxLength: 320 },
            password: { type: 'string', minLength: 1, maxLength: 128 },
        }
    };

    public static modelPaths = [__dirname];

    public static relationMappings: RelationMappings = {

    };

    public fname!: string;
    public lname!: string;
    public username!: string;
    public email!: string;
    public password!: string;
}

Мой tsconfig.json:

{
    "compilerOptions": {
      "target": "es6",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
      "module": "commonjs",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
      "lib": ["es2015"],                             /* Specify library files to be included in the compilation. */
      "outDir": "./build",                      /* Redirect output structure to the directory. */
      "strict": true,                           /* Enable all strict type-checking options. */
      "esModuleInterop": true                   /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
    }
}

Моя структура каталогов:

backend/
    package.json
    tsconfig.json
    express.d.ts
    src/
        models/
            user.ts
        routes/
            secured-api.ts

Что я здесь не так делаю?

Ответы [ 3 ]

0 голосов
/ 04 января 2019

У меня была такая же проблема ...

Не могли бы вы просто использовать расширенный запрос?например:

interface RequestWithUser extends Request {
    user?: User;
}
router.post('something',(req: RequestWithUser, res: Response, next)=>{
   const user = req.user;
   ...
}

С другой стороны, если вы используете асинхронные обратные вызовы с Express, убедитесь, что вы используете упаковщики express-async или убедитесь, что вы точно знаете, что делаете.Я рекомендую: awaitjs

0 голосов
/ 12 февраля 2019

0

Объединение объявлений означает, что компилятор объединяет два отдельных объявления, объявленных с одним и тем же именем, в одно определение.

См. Ниже пример, в котором объявления интерфейса объединяются в машинописном тексте

interface Boy {
height: number;
weight: number;
}

interface Boy {
mark: number;
}

let boy: Boy = {height: 6 , weight: 50, mark: 50}; 

расширить ответ на запрос

0 голосов
/ 04 января 2019

Проблема в том, что вы не увеличиваете глобальное пространство имен Express, определенное express, вы создаете новое пространство имен в своем модуле (файл становится модулем после использования import).

Решение состоит в том, чтобы объявить пространство имен в global

import { User } from "./src/models/user";

declare global {
    namespace Express {
        export interface Request {
            user: User;
        }
    }
}

Или не использовать синтаксис импорта модуля, просто укажите тип:

declare namespace Express {
    export interface Request {
        user: import("./src/models/user").User;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...