如何在Deno中为Oak的Context State对象添加强类型?
解决Deno Oak框架中context.state的强类型问题
你的问题出在泛型参数的错误使用上,Oak的Context和Middleware类型有明确的泛型结构,不需要重复传递State参数,且未给中间件的context指定正确的泛型约束。以下是修正后的实现方案:
核心修正点
- 简化
Middleware类型定义:Middleware的泛型仅需传入你的State接口,无需额外传递Context类型 - 明确
Context的泛型约束:中间件和路由处理函数中的context必须指定为Context<State>,让TypeScript识别state的结构 - 确保路由与应用的泛型一致性:
Router和Application已正确传入State,需保证中间件的类型与它们匹配
修正后的完整代码
import { Application, type Context, type Middleware, Router, } from "https://deno.land/x/oak@v10.6.0/mod.ts"; interface State { userID: number; sessionID: number; } // 修正Middleware类型,仅传入State泛型 const contextMiddleware: Middleware<State> = async ( context: Context<State>, // 明确指定Context的泛型为State next: () => Promise<unknown> ): Promise<void> => { // 此时context.state会自动推导为State类型,拥有强类型提示 context.state.userID = 123; context.state.sessionID = 456; await next(); delete context.state.userID; delete context.state.sessionID; }; const defaultRouter = new Router<State>(); defaultRouter .use(contextMiddleware) .get("/(.*)", (context: Context<State>) => { // 同样指定Context泛型 context.response.status = 404; context.response.body = "Endpoint not available!"; // 此处也能访问context.state的强类型属性 // console.log(context.state.userID); }); const app = new Application<State>(); app.use(defaultRouter.routes(), defaultRouter.allowedMethods()); app.addEventListener("listen", ({ hostname, port, secure }) => { console.log( `Listening on ${secure ? "https://" : "http://"}${ hostname || "localhost" }:${port}`, ); }); await app.listen({ port: 8080 });
为什么这样有效?
Oak的Context类型第一个泛型参数就是自定义的State接口,当你给Application和Router传入State泛型后,它们会自动约束所有关联中间件的context类型。显式给中间件的context指定Context<State>,能确保TypeScript在编写代码时就识别state的结构,提供自动补全和类型校验。
内容的提问来源于stack exchange,提问作者Limos21
相关产品推荐
相关产品推荐

