在打字稿库中导出扩展快递请求

时间:2020-09-25 21:04:49

标签: typescript

我正在尝试创建一个扩展express Response并带有属性warn()的库,当使用该库时,我想使用新的属性warn()

这是我的tsconfig.json

{
  "compilerOptions": {
    "module": "commonjs",
    "esModuleInterop": true,
    "declaration": true,
    "target": "es6",
    "moduleResolution": "node",
    "sourceMap": true,
    "outDir": "dist",
    "baseUrl": ".",
    "paths": {
      "*": ["node_modules/*"]
    },
    "types": ["mocha"],
    "typeRoots": ["@types"]
  },
  "include": ["src/**/*", "test/**/*"]
}

这是我的@types/express/index.d.ts

import * as express from 'express'
import http from 'http'

export {}

declare global {
  namespace Express {
    export interface Response<ResBody = any>
      extends http.ServerResponse,
        express.Response {
      warn(): this
    }
  }
}

src/registerwarn.ts

export function registerwarn() {
  return (_req: Request, res: Express.Response, next): void => {
    res.warn = (): Express.Response => {
      console.log("warning");
      return res;
    };
    return next();
  };
}

src/warnings.ts

import { registerwarn } from './registerwarn'
export default [registerwarn()]

测试:

test/warningtest.ts

import 'should'
import express, { Request, Response } from 'express'
import warnings from '../src/warnings'

describe('test', (): void => {
  const app = express()
  app.use(warnings)
  app.get('/', (req: Request, res: Response) => {
    res.status(200).warn().send({ some: 'content' })
  })
  it('should ', (done) => {
    done()
  })
})

运行tsc会返回以下错误:

src/registerwarn.ts:3:9 - error TS2339: Property 'warn' does not exist on type 'Response'.

     res.warn = (): Express.Response => {
         ~~~~

test/hello_tests.ts:9:21 - error TS2339: Property 'warn' does not exist on type 'Response<any>'.

     res.status(200).warn().send({ some: 'content' })
                     ~~~~


Found 2 errors.

error Command failed with exit code 2.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

如何摆脱这些错误,并确保有人使用npm中的库也不会收到这些警告?

我创建了副本here

1 个答案:

答案 0 :(得分:1)

我已经确定了两种可能的解决方案,尽管我无法评论这是否是“最佳”解决方案-这些仅仅是我想出的。

解决方案I(建议):从mocha的全局声明的types中删除tsconfig.json

根据documentation on tsconfig.json's compilerOptions.types,在mocha下声明types将大大限制@types软件包的可见性。

默认情况下,所有可见的“ @types”软件包都包含在您的编译中。任何封闭文件夹的node_modules / @ types中的软件包都被视为可见。例如,这表示./node_modules/@types/、../node_modules/@types/、../../node_modules/@types/等内的软件包。
如果指定了类型,则仅列出的软件包将包括在全局范围内。例如:

{
  "compilerOptions": {
    "types": ["node", "jest", "express"]
  }
}

此tsconfig.json文件仅包含./node_modules/@types/node、./node_modules/@types/jest和./node_modules/@types/express。在node_modules / @ types / *下的其他软件包将不包括在内。

通过完全放下compilerOptions.types标志,您的输入现在应该可见。

现在,在测试文件中,您应该为import 'mocha'添加一个导入行,以访问测试方法(例如describeit等)。每次测试都需要这样做。我建议使用导入,因为这样可以使声明的来源更加清晰(并且不会因tsconfig.json而突然弹出)。

此外,我不确定您是否也想在此处全局声明mocha,因为mocha测试导入将自动显示在src文件夹中的文件下。我怀疑您使用此标志可能还会遇到其他一些奇怪的错误。

注意:我想您可以使用types标志来替代double-down并将"express"添加到此列表,这会将您的模块扩充定位在@types下。使用此标志,您的里程可能会有很大差异。

解决方案II:在@types字段下明确添加.d.ts include声明。

通过指定compilerOptions.types标志,可见性现在已从您的自定义@types目录中删除。您可以通过修改来自{p>的include标志来破解

"include": ["src/**/*", "test/**/*"]

"include": ["src/**/*", "test/**/*", "@types/**/*.d.ts"]

我不太热衷于此解决方案,因为它无法解决@types不可见的根本原因。您可能会在此路线上遇到奇怪的错误。


在选择以上解决方案(或可能找到替代解决方案)之后,您需要解决项目中的一些键入错误:

  • 警告源的输入似乎与任何app.use重载都不兼容。 tests/hello_tests.ts抱怨app.use(warnings)没有匹配类型的重载。
  • 您无需为extends接口指定任何Response-同一名称空间下的所有接口都将被合并。由于您要声明express.Response上的扩展,即您正在扩展和合并的同一接口,因此该接口声明现在递归地引用自身并导致错误:Type 'Response<ResBody>' recursively references itself as a base type.。删除此extends子句可解决此错误并保留所需的功能。
    declare global {
      namespace Express {
        export interface Response<ResBody = any> {
          warn(): this
        }
      }
    }
    

    请注意,我在此实例中保留了泛型,但它是可选的。如果您有任何新功能需要通用,则应指定它(如上所示)。

这些键入问题解决后,tsc成功退出并且没有报告错误。


顺便说一句,与您的问题无关的是,您的prettier配置的工作日为CRLF / \r\n行的结尾(即每行都有错误)。您应该configure your configuration to be more relaxedspecify a .gitattributes file in your Git repository,以便结帐时默认行尾为LF / \n(而不是CRLF / \r\n)。

相关问题