我正试图更新我的deno项目中模块的版本,但在更新它们之后,我遇到了以下错误,我不明白为什么会发生这种情况。有人遇到过这个问题吗?
错误:
*[错误]:泛型类型'RouterContext<R、 P,S>'需要1到3个类型参数。export const Register=async({request,response}:RouterContext(=>{~~~~~~~~~~~~~在file:///Users/X/Documents/DenoAPP/src/controller.ts:11:53
*
controller.ts:
import {RouterContext} from "https://deno.land/x/oak/mod.ts";
import {Bson} from "https://deno.land/x/mongo@v0.29.2/mod.ts";
import * as bcrypt from "https://deno.land/x/bcrypt/mod.ts";
import {create, verify} from "https://deno.land/x/djwt@v2.4/mod.ts"
import {db} from "./database/connection.ts";
import UserSchema from './schemas/user.ts';
const users = db.collection<UserSchema>("users");
export const Register = async ({request, response}: RouterContext) => {
const {name, email, password} = await request.body().value;
const _id = await users.insertOne({
name,
email,
password: await bcrypt.hash(password)
})
const user = await users.findOne({_id});
delete user.password;
response.body = user;
}
export const Login = async ({request, response, cookies}: RouterContext) => {
const {email, password} = await request.body().value;
const user = await users.findOne({email});
if (!user) {
response.body = 404;
response.body = {
message: 'User not found!'
};
return;
}
if (!await bcrypt.compare(password, user.password)) {
response.body = 401;
response.body = {
message: 'Incorrect password!'
};
return;
}
const jwt = await create({alg: "HS512", typ: "JWT"}, {_id: user._id}, "secret");
cookies.set('jwt', jwt, {httpOnly: true});
response.body = {
message: 'success'
};
}
export const Me = async ({response, cookies}: RouterContext) => {
const jwt = cookies.get("jwt") || '';
if (!jwt) {
response.body = 401;
response.body = {
message: 'unauthenticated'
};
return;
}
const payload = await verify(jwt, "secret", "HS512");
if (!payload) {
response.body = 401;
response.body = {
message: 'unauthenticated'
};
return;
}
const {password, ...userData} = await users.findOne({_id: new Bson.ObjectId(payload._id)});
response.body = userData;
}
export const Logout = async ({response, cookies}: RouterContext) => {
cookies.delete('jwt');
response.body = {
message: 'success'
}
}
RouterContext
是一个通用接口,您必须至少提供第一个类型参数。因为您没有提供任何,所以会收到编译器错误。
这是接口声明:
/** The context passed router middleware. */
export interface RouterContext<
R extends string,
P extends RouteParams<R> = RouteParams<R>,
// deno-lint-ignore no-explicit-any
S extends State = Record<string, any>,
> extends Context<S> {
/** When matching the route, an array of the capturing groups from the regular
* expression. */
captures: string[];
/** The routes that were matched for this request. */
matched?: Layer<R, P, S>[];
/** Any parameters parsed from the route when matched. */
params: P;
/** A reference to the router instance. */
router: Router;
/** If the matched route has a `name`, the matched route name is provided
* here. */
routeName?: string;
/** Overrides the matched path for future route middleware, when a
* `routerPath` option is not defined on the `Router` options. */
routerPath?: string;
}
根据您的评论和您共享的场外代码进行更新:
首先,感谢您提供了一个可复制的示例。
在查看了您的代码后,我发现还有其他不相关的类型问题,我不会在这个答案中尝试解决这些问题。(不过,欢迎您提出新问题。(
这些重构步骤应该可以帮助您解决问题中描述的编译器错误:
首先,最好在每个项目的中心位置管理依赖项(以避免冗长和重复的导入语句,并降低使用相同外部依赖项的不同、不兼容版本的可能性(。这可以通过从一个新模块(./deps.ts
(重新导出外部依赖项,然后从该模块导入所有其他模块来实现:
./deps.ts
:
export * as bcrypt from "https://deno.land/x/bcrypt@v0.3.0/mod.ts";
export {
Application,
Router,
// type RouterContext, // This is removed in favor of the next one
type RouterMiddleware, // This one is new: I included it for a later step in this answer
} from "https://deno.land/x/oak@v10.4.0/mod.ts";
export { Bson, MongoClient } from "https://deno.land/x/mongo@v0.29.2/mod.ts";
export { create, verify } from "https://deno.land/x/djwt@v2.4/mod.ts";
export { oakCors } from "https://deno.land/x/cors@v1.2.2/mod.ts";
然后,在其他需要外部依赖关系的模块中(例如,./src/controller.ts
(:
import { bcrypt, Bson, create, type RouterContext, verify } from "../deps.ts";
// ...
现在,针对您询问的编译器问题:
需要最少重构的解决方案是在中间件函数表达式上使用类型注释,而不是显式键入参数。在您的模块./src/controllers.ts
:中
import {
bcrypt,
Bson,
create,
type RouterMiddleware, // You'll need this type import
verify,
} from "../deps.ts";
// Skipping other module code: just focusing on the middleware...
// before
export const Register = async ({ request, response }: RouterContext) => {/* ... */}; /*
~~~~~~~~~~~~~
Generic type 'RouterContext<R, P, S>' requires between 1 and 3 type arguments.deno-ts(2707) */
// after
export const Register: RouterMiddleware<string> = async (
{ request, response },
) => {/* ... */};
// and make the same change for every other midddleware which currently uses the `RouterContext` type
之后,您应该停止看到您在问题中描述的编译器错误。
只需将上下文传递给RouterContext。示例-
更改此行:exportconstLogin=async({request,response,cookies}:RouterContext(
收件人export const Login=async({request,response,cookies}:RouterContext<</Login>(
基本上,我们需要告诉RouterContext它试图注入依赖的路径是什么