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
相关产品推荐
相关产品推荐

