node.js - 在使用 koa 或 express 组合模块或组合中间件时,调试 typescript 错误的最佳方法是什么?
问题描述
我正在尝试使用 Koa 和 lowdb 建立一个简约的服务器;因为我也在打字稿上写所有东西,所以要满足每个节点包的类型有很多麻烦。
我首先分享我的 .tsconfig。注意:使用 moduleResolution: "node"
{
"compilerOptions": {
"target": "es2017",
"module": "ESNext",
"lib": [
"es6","DOM"
] ,
"allowJs": true,
"outDir": "build",
"rootDir": "src" ,
"strict": true ,
"noImplicitAny": true,
"moduleResolution": "node",
"esModuleInterop": true,
/* Advanced Options */
"resolveJsonModule": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
}
确实设法设置了服务器,但是当我想有效地添加Multer时遇到了很多麻烦,从哪个库中选择来处理传入的数据。
在这篇文章中,有一个很好的讨论,最后我选择使用async-busboy [ ...] 可用的不同库似乎是最新的,当然,带来它自己的类型。
众所周知,koa 将所有内容都视为中间件,因此 async-await 上的包装器很有用!
import multer from '@koa/multer';
import koaStatic from 'koa-static';
import path from 'path';
import asyncBusboy from 'async-busboy';
import multer from '@koa/multer';
import koaStatic from 'koa-static';
import path from 'path';
import asyncBusboy from 'async-busboy';
const router = new Router();
const app = new Koa();
const corsOpt = {
origin: /* process.env.CORS_ALLOW_ORIGIN || */ '*', // this work well to configure origin url in the server
methods: ['GET', 'PUT', 'POST', 'DELETE', 'OPTIONS'], // to works well with web app, OPTIONS is required
allowedHeaders: ['Content-Type', 'Authorization'], // allow json and token in the headers
};
app.use(cors(corsOpt));
app.use(logger());
app.use(koaBody());
app.use(koaStatic(__dirname + './static/uploads'));
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './uploads');
},
filename: function (req, file, cb) {
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);
cb(null, file.fieldname + '-' + uniqueSuffix + '.jpg');
},
});
const upload = multer({ storage });
app.use(upload.any());
app.use(async function (ctx: KoaContext, next: () => any) {
// ignore non-POSTs
if ('POST' != ctx.method) return await next();
const { files, fields } = await asyncBusboy(ctx.req);
console.log(files);
let err = await upload
.single('file')(ctx as any, next)
.then((res: any) => res)
.catch((err: any) => err);
if (err) {
ctx.body = {
code: 0,
msg: err.message,
};
} else {
ctx.body = {
code: 1,
data: files,
};
}
});
// add a route for uploading multiple files
router.post('/uploader', upload.fields([]), (ctx: KoaContext) => {
console.log('ctx.request.files', ctx.request.files);
console.log('ctx.files', ctx);
console.log('ctx.request.body', ctx.request.body);
ctx.body = 'done';
});
// REST OF CODE ...
app.use(router.routes()).use(router.allowedMethods());
app.listen(4040);
console.log('server running ... http://localhost:4040');
我仍在学习,或者说通过做这样的实验来破解所有打字稿的秘密。现在我确实有冲突,因为 mutler 正在做自己的表单数据(我假设通过从其他帖子中读取)到目前为止,这是通过 async-await 从 ctx.req.file 获取文件的解决方案,但我仍然在努力与类型。
当我确实设法让 multer 和 async-busboy 工作时,我不得不删除 koa-body,现在我再次引入这些打字稿错误。
No overload matches this call.
Overload 1 of 4, '(name: string, path: string | RegExp, ...middleware: IMiddleware<any, {}>[]): Router<any, {}>', gave the following error.
Argument of type '(ctx: KoaContext) => void' is not assignable to parameter of type 'string | RegExp'.
Type '(ctx: KoaContext<any, any>) => void' is missing the following properties from type 'RegExp': exec, test, source, global, and 12 more.
Overload 2 of 4, '(path: string | RegExp | (string | RegExp)[], ...middleware: IMiddleware<any, {}>[]): Router<any, {}>', gave the following error.
Argument of type '(ctx: KoaContext) => void' is not assignable to parameter of type 'IMiddleware<any, {}>'.
Types of parameters 'ctx' and 'context' are incompatible.
Type 'ParameterizedContext<any, IRouterParamContext<any, {}>, any>' is not assignable to type 'KoaContext<any, any>'.
我也很难理解 ctx 和 context 之间的区别......
No overload matches this call.
Overload 1 of 4, '(name: string, path: string | RegExp, ...middleware: IMiddleware<any, {}>[]): Router<any, {}>', gave the following error.
Argument of type 'Middleware<DefaultState, DefaultContext, any>' is not assignable to parameter of type 'string | RegExp'.
Type 'Middleware<DefaultState, DefaultContext, any>' is missing the following properties from type 'RegExp': exec, test, source, global, and 12 more.
Overload 2 of 4, '(path: string | RegExp | (string | RegExp)[], ...middleware: IMiddleware<any, {}>[]): Router<any, {}>', gave the following error.
Argument of type 'Middleware<DefaultState, DefaultContext, any>' is not assignable to parameter of type 'IMiddleware<any, {}>'.
Types of parameters 'context' and 'context' are incompatible.
Type 'ParameterizedContext<any, IRouterParamContext<any, {}>, any>' is not assignable to type 'ParameterizedContext<DefaultState, DefaultContext, any>'.
Type 'ExtendableContext & { state: any; } & IRouterParamContext<any, {}> & { body: any; response: { body: any; }; }' is missing the following properties from type 'DefaultContext': file, files
Overload 3 of 4, '(path: string | RegExp | (string | RegExp)[], middleware: Middleware<DefaultState, DefaultContext, any>, routeHandler: IMiddleware<any, DefaultContext>): Router<...>', gave the following error.
Argument of type '(ctx: KoaContext) => void' is not assignable to parameter of type 'IMiddleware<any, DefaultContext>'.
Types of parameters 'ctx' and 'context' are incompatible.
Type 'ParameterizedContext<any, DefaultContext & IRouterParamContext<any, DefaultContext>, any>' is not assignable to type 'KoaContext<any, any>'.
Types of property 'request' are incompatible.
Type 'Request' is not assignable to type 'KoaRequest<any>'.
Property 'body' is optional in type 'Request' but required in type 'KoaRequest<any>'.
你也可以在这里查看整个项目repo
对类型的任何帮助都会很棒。
希望它有助于使用带有 typescript 的 koa 进一步讨论。
解决方案
推荐阅读
- python - 如何加快涉及前一行和多行 pandas 的计算?
- logging - 当持续时间是麋鹿日志中的 MDC 字段时,如何绘制查询的持续时间
- python - 为 numpy 数组重载“==”运算符
- java - 没有 AsyncTask 的 ProgressBar
- javascript - React Javascript - Visual Studio Code 不会自动完成对象属性
- sparql - 选择依赖树上的连接顶点并按深度排序(SPARQL)
- python - 如何修复“ValueError:长度不匹配”
- bash - bash:读取命令有时只打印换行符
- loops - 如何使用 for 循环在 Terraform 中发出对象列表?
- java - 当对象也在 ArrayList 中时,如何访问该对象的 ArrayList 属性?