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

使用express-session结合Redis Store时遇TypeScript错误求助

解决Express-Session + Redis Store的TypeScript错误

问题根源

connect-redis v7及以上版本的API做了变更:不再通过new RedisStore()实例化存储对象,而是直接调用导出的工厂函数;同时TypeScript类型定义需要更明确的关联,否则会出现构造签名缺失、属性不存在的错误。


方案1:使用官方Redis客户端(redis@4+ + connect-redis@7+)

修正后的完整代码:

import express, { Request } from "express";
import { expressMiddleware } from "@apollo/server/express4";
import startApolloServer from "./graphql";
import RedisStore from "connect-redis";
import session from "express-session";
import { createClient } from "redis";

async function init() {
  const app = express();

  // 创建Redis客户端,可根据需要添加连接配置(如url、密码)
  const redisClient = createClient();
  redisClient.connect().catch(console.error);

  // connect-redis v7+ 直接调用工厂函数,无需new
  const redisStore = RedisStore({
    client: redisClient,
    prefix: "myapp-session:", // 可选:给session键名加前缀,避免和其他Redis数据冲突
  });

  // 扩展Request类型,让TypeScript识别req.session属性
  const context = async ({ req }: { req: Request & { session: session.Session } }) => ({
    session: req.session,
  });

  app.use(express.json());
  app.use(
    session({
      store: redisStore,
      name: "connect.sid",
      secret: process.env.SESSION_SECRET || "dev-secret", // 生产环境建议用环境变量存密钥
      resave: false,
      saveUninitialized: false,
      cookie: {
        httpOnly: true,
        secure: process.env.NODE_ENV === "production", // 生产环境开启HTTPS时设为true
        sameSite: "lax" as const, // 明确类型避免TS报错
        maxAge: 1000 * 60 * 60 * 24 * 7, // 7天有效期
      },
    })
  );

  app.use(
    "/graphql",
    expressMiddleware(await startApolloServer(), { context })
  );

  app.listen(4000, () => {
    console.log("Server running on port 4000: http://localhost:4000/graphql");
  });
}

init();

方案2:使用ioredis客户端

如果习惯用ioredis,按以下方式调整:

import express, { Request } from "express";
import { expressMiddleware } from "@apollo/server/express4";
import startApolloServer from "./graphql";
import session from "express-session";
import Redis from "ioredis";
import RedisStore from "connect-redis";

async function init() {
  const app = express();

  // 创建ioredis客户端
  const redisClient = new Redis({
    host: "localhost", // 按需配置Redis地址
    port: 6379,
  });

  // 同样直接调用RedisStore工厂函数
  const redisStore = RedisStore({
    client: redisClient,
  });

  // 扩展SessionData类型,定义你的session数据结构(可选但推荐)
  declare module "express-session" {
    interface SessionData {
      userId?: string;
      // 其他你需要存在session里的字段
    }
  }

  const context = async ({ req }: { req: Request }) => ({
    session: req.session,
  });

  app.use(express.json());
  app.use(
    session({
      store: redisStore,
      name: "connect.sid",
      secret: process.env.SESSION_SECRET || "dev-secret",
      resave: false,
      saveUninitialized: false,
      cookie: {
        httpOnly: true,
        secure: process.env.NODE_ENV === "production",
        sameSite: "lax" as const,
        maxAge: 1000 * 60 * 60 * 24 * 7,
      },
    })
  );

  app.use(
    "/graphql",
    expressMiddleware(await startApolloServer(), { context })
  );

  app.listen(4000, () => {
    console.log("Server running on port 4000: http://localhost:4000/graphql");
  });
}

init();

核心修复点

  1. 移除new关键字:connect-redis v7+ 导出的是工厂函数,直接调用即可,解决TS7009构造签名缺失错误
  2. 类型扩展:通过Request & { session: session.Session }或扩展SessionData接口,让TypeScript正确识别session属性
  3. 参数类型修正:sameSite用as const明确类型,避免TS报错
  4. 安全优化:用环境变量存储session密钥,不要硬编码在代码中

内容的提问来源于stack exchange,提问作者Varun Panyam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 22:37:51