You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 01:54:12