[英]Export extended express request in typescript library
I'm trying to create a library which extends the express
Response
with a property warn()
and when using the library I want to have the new property warn()
available.我正在尝试创建一个库,该库使用属性
warn()
扩展express
Response
,并且在使用该库时,我希望新的属性warn()
可用。
This is my tsconfig.json
这是我的
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/**/*"]
}
This is my @types/express/index.d.ts
:这是我的
@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
: 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
: src/warnings.ts
:
import { registerwarn } from './registerwarn'
export default [registerwarn()]
A test:一个测试:
test/warningtest.ts
: 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()
})
})
Running tsc
returns these errors:运行
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.
How can I get rid of these errors and make sure if somebody uses the library from npm
doesn't get these warnings as well?我怎样才能摆脱这些错误,并确保是否有人使用
npm
中的库也没有收到这些警告?
There are two possible solutions here I have identified, although I am unable to comment whether this is the "best" solution available - these are merely what I came up with.我在这里确定了两种可能的解决方案,尽管我无法评论这是否是可用的“最佳”解决方案 - 这些只是我想出的。
mocha
from globally declared types
in tsconfig.json
tsconfig.json
全局声明的types
中删除mocha
As per the documentation on tsconfig.json
's compilerOptions.types
, declaring mocha
under types
will significantly restrict the visibility of @types
packages.由于每对文档
tsconfig.json
的compilerOptions.types
,宣告mocha
下types
将显著限制的知名度@types
包。
By default all visible ”@types” packages are included in your compilation.
默认情况下,所有可见的“@types”包都包含在您的编译中。 Packages in node_modules/@types of any enclosing folder are considered visible.
任何封闭文件夹的 node_modules/@types 中的包都被认为是可见的。 For example, that means packages within ./node_modules/@types/, ../node_modules/@types/, ../../node_modules/@types/, and so on.
例如,这意味着 ./node_modules/@types/、../node_modules/@types/、../../node_modules/@types/ 等中的包。
If types is specified, only packages listed will be included in the global scope.如果指定了类型,则仅列出的包将包含在全局范围内。 For instance:
例如:
{ "compilerOptions": { "types": ["node", "jest", "express"] } }
This tsconfig.json file will only include ./node_modules/@types/node, ./node_modules/@types/jest and ./node_modules/@types/express.
此 tsconfig.json 文件将仅包含 ./node_modules/@types/node、./node_modules/@types/jest 和 ./node_modules/@types/express。 Other packages under node_modules/@types/* will not be included.
node_modules/@types/* 下的其他包将不包含在内。
By dropping the compilerOptions.types
flag altogether, your typing should now be visible.通过完全删除
compilerOptions.types
标志,您的输入现在应该是可见的。
Within your test file, you should now add an import line for import 'mocha'
to gain access to testing methods (eg describe
, it
, etc).在您的测试文件中,您现在应该为
import 'mocha'
添加一个导入行以访问测试方法(例如describe
、 it
等)。 This will need to be done for each test.每次测试都需要这样做。 I would recommend using an import, as it is a bit clearer where your declarations are coming from (and not invisibly popping up as a result of your
tsconfig.json
).我建议使用导入,因为它更清楚你的声明来自哪里(并且不会因为你的
tsconfig.json
不可见地弹出)。
Additionally, I am not sure that you would want mocha
to be declared globally here either, as mocha
test imports would automatically be visible under files in the src
folder.另外,我不知道,你想
mocha
在全球范围内无论是在这里声明,如mocha
测试进口将自动成为下的文件可见src
文件夹。 I suspect you might run into some other strange errors using this flag.我怀疑您使用此标志可能会遇到其他一些奇怪的错误。
Note: I suppose you could alternative double-down with the
types
flag and add"express"
to this list, which will locate your module augmentation under@types
.注意:我想您可以使用
types
标志替代加倍并将"express"
添加到此列表中,这将在@types
下找到您的模块扩充。 Your mileage may vary significantly with this flag.您的里程可能会因此标志而有很大差异。
@types
.d.ts
declarations under the include
field.include
字段下显式添加@types
.d.ts
声明。 By specifying the compilerOptions.types
flag, visibility is now removed from your custom @types
directory.通过指定
compilerOptions.types
标志,现在可以从您的自定义@types
目录中删除可见性。 You can hack this back in by modifying the include
flag from您可以通过修改
include
标志
"include": ["src/**/*", "test/**/*"]
to到
"include": ["src/**/*", "test/**/*", "@types/**/*.d.ts"]
I am not too keen on this solution, as it does not address the underlying cause of @types
not being visible.我不太喜欢这个解决方案,因为它没有解决
@types
不可见的根本原因。 You may experience strange errors with this route.您可能会遇到此路线的奇怪错误。
After choosing a solution above (or possibly finding an alternative solution), you need to resolve a few typing errors in the project:在选择上述解决方案(或可能找到替代解决方案)后,您需要解决项目中的一些打字错误:
app.use
overload.app.use
重载不兼容。 tests/hello_tests.ts
is complaining about no matching type overload for app.use(warnings)
. tests/hello_tests.ts
抱怨app.use(warnings)
没有匹配的类型重载。extends
for your Response
interface - all interfaces under the same namespace will be merged.Response
接口指定任何extends
- 将合并同一名称空间下的所有接口。 Since you are declaring an extends on express.Response
, the same interface you are augmenting and merging, the interface declaration is now recursively referencing itself and causing an error: Type 'Response<ResBody>' recursively references itself as a base type.
express.Response
上声明了一个 extends ,即您正在扩充和合并的同一接口,接口声明现在递归地引用自身并导致错误: Type 'Response<ResBody>' recursively references itself as a base type.
. extends
clause resolves this error and preserves the functionality you desire.extends
子句可解决此错误并保留您想要的功能。 declare global { namespace Express { export interface Response<ResBody = any> { warn(): this } } }
Note that I preserved the generic in this instance, but it is optional.
请注意,我在本例中保留了泛型,但它是可选的。 If any of your new functionalities require the generic, you should specify it (as demonstrated above).
如果您的任何新功能需要泛型,您应该指定它(如上所示)。
After these typing issues are resolved, tsc
exits successfully and reports no errors.解决这些键入问题后,
tsc
成功退出并且不报告任何错误。
As an aside that is unrelated to your question, your prettier
configuration is having a field day with CRLF
/ \\r\\n
line endings (ie an error on every line).顺便说一句,与您的问题无关,您
prettier
配置有一个带有CRLF
/ \\r\\n
行结尾的字段日(即每一行都有错误)。 You should configure your configuration to be more relaxed , or specify a .gitattributes
file in your Git repository so that line endings are LF
/ \\n
(and not CRLF
/ \\r\\n
) by default on checkout.您应该将配置配置为更宽松,或者在您的 Git 存储库中指定一个
.gitattributes
文件,以便在结帐时默认情况下行尾是LF
/ \\n
(而不是CRLF
/ \\r\\n
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.