即使在减速文件打字稿中指定,也找不到属性

时间:2020-08-05 20:50:44

标签: typescript express typescript-typings .d.ts

尝试从在“ express-request-id”中间件中定义并在打字稿声明文件中声明的快速请求对象中读取属性时,会引发错误。

我的d.ts文件具有以下定义:

(server.d.ts)

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

这应该是正确的。根据我的研究,这种方法行不通的唯一方法就是不好地引用它。我引用它的方式是通过tsconfig中的files字段,如下所示:

{
    "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/**/*"
    ]
}

造成错误的代码如下: (服务器/中间件/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 个答案:

答案 0 :(得分:1)

最后,我解决了这个问题,而不是使用有问题文件内部使用全局声明的声明文件。 像这样:

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