Свойство не найдено, даже если указано в машинописном тексте файла замедления - PullRequest
1 голос
/ 05 августа 2020

При попытке чтения свойства из объекта запроса express, определенного в промежуточном программном обеспечении 'express -request-id' и объявленного в файле объявления машинописного текста, он выдает ошибку.

My d. ts-файл имеет следующие определения:

(server.d.ts)

declare namespace Express {
    export interface Request {
        id: string
    }
}

Это должно быть правильно. Согласно моим исследованиям, единственный способ, при котором это не сработает, - это плохая ссылка на него. Я ссылаюсь на это через поле files в моем tsconfig, например:

{
    "compilerOptions": {
        "strict": true,
        "noImplicitAny": true,
        "target": "ESNext",
        "watch": true,
        "lib": ["ESNext", "ES7"],
        "types": ["node"],
        "moduleResolution": "node",
        "baseUrl": "./",
        "esModuleInterop": true,
        "allowSyntheticDefaultImports": true,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "strictPropertyInitialization": false
    },
    "compileOnSave": true,

    "typeAcquisition": { "enable": true },

    // referenced here.
    "files": ["./server.d.ts"],

    // i have also tryed refrenceing it here and in a triple slash directive.
    "include": [
        "./*.ts",
        "./server/**/*.ts",
        "./shared/**/*.ts",
        "./api/**/*.ts",
        "./database/**/*.ts",
        "./builders/**/*"
    ]
}

Часть кода, которая создает ошибку, выглядит следующим образом: (server / middleware / reqTerminator.ts)


import { Request, Response, NextFunction } from 'express'

// when testing triple slash directives they wore used here like the folowing:
// /// <reference types="../../server.d.ts" />

export const [completeRequest, middleware] = (() => {
    const connections = new Map<string, NodeJS.Timeout>()

    const completeRequest = async (request: Request, response: Response) => {
        const timeout = connections.get(request.id)
        if (timeout) clearTimeout(timeout)
        response.end()
        return connections.delete(request.id)
    }

    return [
        completeRequest,
        async (request: Request, response: Response, nextF: NextFunction) => {
            connections.set(
                request.id,
                setTimeout(() => {
                    completeRequest(request, response)
                }, 2000),
            )
            nextF()
        },
    ]
})()

export default middleware

ошибка:

⨯ Unable to compile TypeScript:
server/middleware/reqTerminator.ts:7:43 - error TS2339: Property 'id' does not exist on type 'Request<ParamsDictionary, any, any, ParsedQs>'.

7       const timeout = connections.get(request.id)
                                                ~~
server/middleware/reqTerminator.ts:10:37 - error TS2339: Property 'id' does not exist on type 'Request<ParamsDictionary, any, any, ParsedQs>'.

10      return connections.delete(request.id)
                                          ~~
server/middleware/reqTerminator.ts:17:13 - error TS2339: Property 'id' does not exist on type 'Request<ParamsDictionary, any, any, ParsedQs>'.

17                      request.id,

Выполняется с ts-node с соответствующим проектом.

1 Ответ

1 голос
/ 06 августа 2020

В конце концов, я решил эту проблему, вместо использования файла объявления, используя глобальное объявление внутри файла c проблемы. Вот так:

import { Request, Response, NextFunction } from 'express'

// declaration start:
declare global {
    namespace Express {
        interface Request {
            id: string
        }
    }
}


export const [completeRequest, middleware] = (() => {
    const connections = new Map<string, NodeJS.Timeout>()

    const completeRequest = async (request: Request, response: Response) => {
        const timeout = connections.get(request.id)
        if (timeout) clearTimeout(timeout)
        response.end()
        return connections.delete(request.id)
    }

    return [
        completeRequest,
        async (request: Request, response: Response, nextF: NextFunction) => {
            connections.set(
                request.id,
                setTimeout(() => {
                    completeRequest(request, response)
                }, 2000),
            )
            nextF()
        },
    ]
})()

export default middleware
...