我正在尝试创建一个扩展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。
答案 0 :(得分:1)
我已经确定了两种可能的解决方案,尽管我无法评论这是否是“最佳”解决方案-这些仅仅是我想出的。
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'
添加一个导入行,以访问测试方法(例如describe
,it
等)。每次测试都需要这样做。我建议使用导入,因为这样可以使声明的来源更加清晰(并且不会因tsconfig.json
而突然弹出)。
此外,我不确定您是否也想在此处全局声明mocha
,因为mocha
测试导入将自动显示在src
文件夹中的文件下。我怀疑您使用此标志可能还会遇到其他一些奇怪的错误。
注意:我想您可以使用
types
标志来替代double-down并将"express"
添加到此列表,这会将您的模块扩充定位在@types
下。使用此标志,您的里程可能会有很大差异。
@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 relaxed或specify a .gitattributes
file in your Git repository,以便结帐时默认行尾为LF
/ \n
(而不是CRLF
/ \r\n
)。