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

TypeScript中ah-sequelize-plugin配置扩展的类型不匹配问题

解决Actionhero中ah-sequelize-plugin的配置类型不匹配问题

问题场景

在TypeScript版Actionhero项目中集成ah-sequelize-plugin时,为解决api.sequelize无类型提示、被标记为any的问题,在tsconfig.json中添加了:

"include": ["./src/**/*", "node_modules/ah-sequelize-plugin/**/*.d.ts"]

但随之出现websocket配置的类型不匹配错误,具体报错:

Subsequent property declarations must have the same type.  Property '[namespace]' must be of type '{ enabled: boolean; clientUrl: string; clientJsPath: string; clientJsName: string; destroyClientsOnShutdown: boolean; server: { authorization: any; pathname: string; parser: string; transformer: string; ... 6 more ...; exposed: boolean; }; client: { ...; }; }', but here has type '{ enabled: boolean; clientUrl: string; clientJsPath: string; clientJsName: string; destroyClientsOnShutdown: boolean; server: {}; client: { apiPath: string; cookieKey: string; }; }'

相关代码片段

第三方插件websocket.d.ts代码:

import { ActionheroConfigInterface } from "actionhero";
declare const namespace = "websocket";
declare module "actionhero" {
    interface ActionheroConfigInterface {
        [namespace]: ReturnType<typeof DEFAULT[typeof namespace]>;
    }
}
export declare const DEFAULT: {
    websocket: (config: ActionheroConfigInterface) => {
        enabled: boolean;
        clientUrl: string;
        clientJsPath: string;
        clientJsName: string;
        destroyClientsOnShutdown: boolean;
        server: {};
        client: {
            apiPath: string;
            cookieKey: string;
        };
    };
};
export {};

自定义websocket配置代码:

import { ActionheroConfigInterface } from "actionhero";

const namespace = "websocket";

declare module "actionhero" {
  export interface ActionheroConfigInterface {
    [namespace]: ReturnType<(typeof DEFAULT)[typeof namespace]>;
  }
}

export const DEFAULT = {
  [namespace]: (config: ActionheroConfigInterface) => {
    return {
      enabled: true,
      clientUrl: "window.location.origin",
      clientJsPath: "javascript/",
      clientJsName: "ActionheroWebsocketClient",
      destroyClientsOnShutdown: false,
      server: {
        authorization: null,
        pathname: "/ws",
        parser: "JSON",
        transformer: "websockets",
        plugin: {},
        pingInterval: 30000,
        origins: "*",
        methods: ["GET", "HEAD", "PUT", "POST", "DELETE", "OPTIONS"],
        credentials: true,
        maxAge: "30 days",
        exposed: false,
      },
      client: {
        apiPath: "/api",
        cookieKey: config.web.fingerprintOptions.cookieKey,
        timeout: 10000,
        pingTimeout: 45000,
        strategy: ["online", "timeout", "disconnect"],
        manual: false,
        websockets: true,
        network: true,
        transport: {},
        queueSize: Infinity,
      },
    };
  },
};

plugins.ts代码:

import { PluginConfig } from "actionhero";
import * as path from "path";

const namespace = "plugins";

declare module "actionhero" {
  export interface ActionheroConfigInterface {
    [namespace]: ReturnType<(typeof DEFAULT)[typeof namespace]>;
  }
}

export const DEFAULT: { [namespace]: () => PluginConfig } = {
  [namespace]: () => {
    const sequelizePlugin =
      process.env.NODE_ENV === "build"
        ? {}
        : {
            "ah-sequelize-plugin": {
              path: path.join(
                process.cwd(),
                "node_modules",
                "ah-sequelize-plugin"
              ),
            },
          };
    return sequelizePlugin;
  },
};

问题原因

第三方插件的websocket.d.ts已经对ActionheroConfigInterface的websocket属性做了类型声明(server为{}, client仅包含apiPath和cookieKey)。而自定义配置中,重复声明了ActionheroConfigInterface的websocket属性,且类型基于自身的DEFAULT返回值,与第三方的类型定义冲突,导致TypeScript报错。

解决方法

1. 删除重复的接口声明

自定义websocket配置文件中,移除重复的declare module "actionhero"代码块,因为第三方已经完成了websocket属性的类型声明,无需重复定义。

2. 对齐第三方的类型约束

导入第三方插件的默认配置类型,让自定义配置的返回值符合该类型:

import { ActionheroConfigInterface } from "actionhero";
// 导入第三方websocket的默认配置类型(路径需根据插件实际结构调整)
import { DEFAULT as WebsocketDefault } from "ah-sequelize-plugin/dist/websocket";

const namespace = "websocket";

// 移除重复的declare module代码

export const DEFAULT = {
  [namespace]: (config: ActionheroConfigInterface): ReturnType<typeof WebsocketDefault[namespace]> => {
    return {
      enabled: true,
      clientUrl: "window.location.origin",
      clientJsPath: "javascript/",
      clientJsName: "ActionheroWebsocketClient",
      destroyClientsOnShutdown: false,
      server: {
        authorization: null,
        pathname: "/ws",
        parser: "JSON",
        transformer: "websockets",
        plugin: {},
        pingInterval: 30000,
        origins: "*",
        methods: ["GET", "HEAD", "PUT", "POST", "DELETE", "OPTIONS"],
        credentials: true,
        maxAge: "30 days",
        exposed: false,
      },
      client: {
        apiPath: "/api",
        cookieKey: config.web.fingerprintOptions.cookieKey,
        timeout: 10000,
        pingTimeout: 45000,
        strategy: ["online", "timeout", "disconnect"],
        manual: false,
        websockets: true,
        network: true,
        transport: {},
        queueSize: Infinity,
      },
    };
  },
};

3. 优化tsconfig.json的include路径(可选)

将include路径调整为更精准的范围,避免加载不必要的类型文件:

"include": ["./src/**/*", "node_modules/ah-sequelize-plugin/dist/**/*.d.ts"]

验证

修改完成后,重新运行TypeScript编译,类型不匹配错误将消失,同时api.sequelize的类型提示保持正常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 09:52:33